IMD 1.12: 12/12/2009 12:28:07 dual cpm 1.0  OBN Zpr$<,N Z| O`W NsNVH*nJgH>?<N TO`JL N^NuNVH>.0`".aN.a`.a`J@gڰ|g|g.aNJLN^NuNVH*n.6Bg?<N XO.Bg?<N XO|m>ajB- .Bg?<N XOJ@g>aJ&|6 S`fJkf>a0(k.+ޫ>d/ /<6NnPOddJo:.Bg?<N XO.Bg?<N XOJ@g>a` +JL8N^NuNVBW?<N TOJ@gBWa.a-@.aV..aL nNN^Nu$/` 4/`"/`2/0/HN ZLxNu/H/Nu/ o / 0H@0 _NuNV|B.-n-n -y6.N N^NuNV.60n/aXON^NuNVH *n (y6BGlbL0|f<N>aJ@gp`8?0|HH@B@H@й6// nN J@g0|`RG`0<JL0N^NuNVH. H||op`FB.GB..N #6fp` y6# 6 y6#6B@JL N^NuNVH *n(n >.0SGJ@g`JL0N^NuNVH *n(n ~  ?HH@|gJgB@`LSGJGfJ.g> ?g HH@"y6)HFAgB@`TTHH@|?gB@`pJL0N^NuNVH*n>/. / abPOg- > / /. a POG HJL N^NuNVH *n(y6,H- H,HArF`>0- H|4aAJL0N^NuNVH*n>. Jng0G>N` ` 5pH|JL N^NuNVH*y6B0.-HH-H. HBHЁ-@.6/.N@XOJL N^NuNVH*n-<?- R< mBR<@mp``H-H|?Af*H- H@"y6)HFA|fF B@`$GF ./<NXO|ep`B@JL N^NuNVH *n~I J$fSGJGf y6 hcOBp"y6)HAo0"y6)HF- HB|AJL0N^NuNVH*n.a>- H@f-H|``- H@c0<``B@JL N^NuNVH*n y68(| - f.aJ@gp`LB- .a- H|Abp`2.a<>?/ a\O>JGfp`- H>?aTOR- JL N^NuNVH>.<. *n 0`TH>?<NTO`V>N`NBB- B-./<NXO`2B.N `&#6`p``H |^rW hNB@JL N^NuNVH*nH`-H>-H??< NXO+@`|(m&l.Y?/-N(\O>0+W?< NTO.?.?<NXO>?< NTO. ?< NTO> N`` J@gj|gB@JL8N^NuaBNu @lH {NNu T h h h  h h h h > F Z h h N hv h h h~9<gNu <&@a<aa*~&49$f9*?a>( Jg|ּؼ"D&'C Nu36Nu4Nu BH0HNu#,Nu9gNuA$9g9g`NuxaxaxFaNu9gNuaxaa9$  Nutxa<aaWNutxa<a|avaWgaNu<ab<aZah9$<Nu<JaB<a:azaDNut<9:g9?g9@&ּ "CA9= ;=NuA1AvaQaaNu#0<9:aadza89$||@gQpNupNup,*<96B9=J9>g:|=N3:9 Z f n 2@? 4 4@< < @@+ @W@     %&'()*+, -. /0  12!"34#$!"#$1234%&'(5678 )*+,9:;<  -./0 12345678 !"#$%&'(9:;<=>?@)*+,-./02L5REDNS 68K REDNS 68K UVWXYPIP 68KD STAT 68KIAS68 68KAS68 68K !"#$%&AS68 68K$'()AS68SYMBDAT'*+,TEST TBI-LO68 68K{./012345DDT 68K!678DDT1 68K9:;<=>?@DDT1 68KABCDEFGHDDT1 68K ICPM SYSJKLMNOPQCPM SYS+RSTREDNS 68KMZ[\]^TBI68K 68K_`TBI S abcdefghTBI S ijklmnopTBI S qrstuvwxTBI S yzTBI68K2 68K{|TBI68K S }~TBI68K S TBI68K S TBI68K S  TBI 68KTEST1 TBINEWTBI 68KRANDOM TBINEWTBI S gBW?.N1FTO`. NG\NI=@>aJ@g=n` >N5`.NG\NI=@>aJ@g=n` >N9*`f.NG\NI>N-T`J>aLJ@g`> nf >N2` nf >N-T`H |"r$W hN`N^NuNV . g . l . mB@`pN^NuNVN<..#NG\.adn.H`p`p`p``|g|g|g.HHм @g .H| `.H|gfR.N*B-@ nJf`2.Y/.NMXO|fBW?.N1FTO` .-N,2`*.>/a"XOJ@g.ND`.E/aXOJ@gNNG`.K/aXOJ@g.N`.P/aXOJ@g 3.`.X/aXOJ@g 3.`f.a/a^XOJ@g 3.`B.j/a:XOJ@g 30`.r/aXOJ@g 30`.{/aXOJ@g 30`./aXOJ@g 30`./aXOJ@g 30`./aXOJ@g 30`j./abXOJ@g.N`@./a8XOJ@f./a NEWTBI S NEWTBI S NEWTBI S ASM SUBTIME TBI`v`4C Runtime V01.04 Copyright 1982 by Digital Research o"h&IB[b#0E?/ NufN~NVB odpN^NuNV0/"/ NB0d0< Av"NB0<NBN^NuNVNGBWN?B94.N|f`NSp=@=@3.3030>NBNC&NCND`N.*N;>BgNCTO>ND.JN) .ZN) .N) .N) .N) .N) .N) BWND.N|fBnNP8|f">NQN.*BW?<N1FTO` nm|.NG\./.N"XO n ./.NXO..Nʰ|fNJ `">?<?<NV,XO>BgNCTO`">?<?<NV,XO>BgNCTO.NBnBn0.`:.NG\`D.NG\`6.NG\`(.NG\``|gΰ|g|gа|gJng =nBn` NI=@ n f=n ng nf <2.HЁ @g 0.| `0.=@0.`=|`=|`=|`=|`=|`v=|`l=|`b=|`Z=|`R=|`J=|`B=|`:=|`2=|XOJ@gN(x|f NPp``./aXOJ@g NqJ`./aXOJ@g.N`./aXOJ@g.N`~./avXOJ@g.N>`T./aLXOJ@g N`2./a*XOJ@g.N`./aXOJ@g.N`./aXOJ@f./aXOJ@g.NNG`./aXOJ@g.N`l./adXOJ@g.NNG`<./a4XOJ@g ByT`./aXOJ@g N`./aXOJ@g Np`./aXOJ@g.N`./aXOJ@g&J94f. N,2` NWp`x`n./afXOJ@g.N$`D./a>XOJ@g 3T`$.#/aXOJ@g` .$N,209.N^NuNV n JgJ nHHм @g nH| ` nH"n HAgB@`.`RR ` nJg n  g n  gB@`pN^NuNVNC =@NC=@NG=@BW?.NCTONDBnNI@| gXND .g .g .`*=|`"=|```H |rW h@N=n nf=n0.``a=@ nf>BgNCTONBb`z`rp=@=@`dp=@=@`Vp=@=@`H=n=|`8N7b090=@=@` N7090=@=@`N: =y0`N/=y0`N6`N7`N0`N,`N4``N8V`N,v`N.:`N.`N:`.NG\NI>N2`bNJ N*^J@fN/NVJ@gN/```4BWNU\?NC?p_WW NUj_l NUj?`NU\?NC?p_WW N1FTO`BWNC?NU\_|lBg`NU\?NCWWN1FTO`BWNU\|lBg` NU\?WN1FTO`xBWNU\?W NUj_l NUj?` NU\?W N1FTO`>NJ NP J@fN*^J@fN: ``BWNC?NU\_R@lBg`NU\?NCWRWN1FTO=|`BWNU\?WNCWNUj_l NUj?`NU\?WNCWN1FTO=|`BWNU\?W NCWRWNUj_l NUj?`NU\?W NCWRWN1FTO` NC^`0n"n0H>NC^Rn`` .fBW?.NCTONDBn`~ . f.0.n|Ol 0.HЮ @ Rn> NC^`F . m .f``00.n|Ol"0.HЮ @Rn.H>NC^ND` .2.HЁ @B>?.NCTON^NuNV>/]?<}/Y?</U/.a|f`>Bg?<?.?.aPON^NuNVa|f@B94NCNUxN;>BgNCTO>?<?<NV,XONDN^NuNVBW/<P/<8/.a N^NuNV>/]?NQ>0.WRWN[>NQN.*BW?.N1FTON^NuNV./.a2XO|f`J.f.mat`x.aT-@.al-@>/?/]?<}/YNU\?RW/U/.a|fp`BW?<Bg?.?.aPON^NuNV>/Y?NQ`0 nadfN.*BW?.jN1FTON^NuNV^>/6N_~XO=@j njl0.j`0<=@j N2njB(6JngJng0.njgp`P`0.njop`>Jng 0.jn`B@=@h n=PfBnd0.hnjl .2.HЁ. 2.hHЁ/6aXOJ@fJnfJngp``Rnh``=|d nafg$>hNU\?N1FTONJ NC =@b nf>h/. .2.HЁ//l/6a.lNF>/lNWfXO nafg4NC>BgNCTONU\>NVNC>?.bNCTOJnfp` naffL>/6N_~XO=@j njl0.j`0<=@j N2njB(6. NFnh`JnfZ..NG\NI=@f <2.fHЁ @g 0.f| `0.f=@f nnfgp`R`0.nh`$.;NG\NI=@f <2.fHЁ @g 0.f| `0.f=@f n0f nyfg naff<>/6N_~XO=@j njl0.j`0<=@j N2njB(6`T.6NF>/6NWfXONC>BgNCTONU\>NVNC>?.bNCTO nyfg naff. NFnh` nnff.NFnh`p` JnfJngB@``JndgB@`pN^NuNV>/Y?ah?NCTON^NuNV09ym. H>a` <629HЁ @P <629HЁ @ >?9/<6N@\O>RW/<6N@xXO=@ nOo2 <629HЁ @>?9/<6N@\O`3Rya a ,N^NuNV3N^NuNVNC ?a d_lNC>NC ?SWNCTO`ZJyf`P3=y0.yl$0n6"<64.H҂"AQRn`SySya N^NuNVJyo<09yf.NC ?a _nNC>NC ?SWNCTO`Jyf`309R@=@0.yl$0n6"<64.H҂"AQRn`09R@ymJyoSySy09yfJyoSya N^NuNVNC =@a vNVJ@gBa VJ@g8NU\>Wa >?<NU\?RWNV,XO>BgNCTO`XNPa >a d3a J@g"NU\>Wa >?.NCTO`NC>RW?.NCTON^NuNV3a NC>a .?NCTON^NuNV09yf aa`Ry09yl*0y"|60H=@ n g n a/?NQN.*BW?.N1FTON^NuNV&NU\=@*>/.?<}/0?</2/.a2|f`.6NG\=n2,0.,n0nBWN?aR|f`~>N?>,NQRn,NPJ@g`X>/6N_~XO=@4 n4l0.4`0<=@4 N2n4| 6BW/6NA,XONBb`dBWN?>*NQN^NuNV.$/.aXO|fB@`J.$f.Da8B@`a tJ@fB@`.$NMFJ@f.VaB@`f.fNG\.4/$NMhXONGNDNUx.4Ni NW>NQN.*BW?<N1FTOpN^NuNV>/</<t/.a < N^NuNV.4/.aXON^NuNV.a @-@Y?</U/.a2|f`">NBN.*BWNU\?N1FTON^NuNV*../.NJXO-@Jf.Pa`~.NG\> NQJn gNP>/4/.NKPO=@0m4 n0o.`a=|0>0/4N`XONP`.NJN^NuNV$.NG\.(/.NJXO-@Jf.pa&`NU\=@> NQ0.n R@=@Jng>/*N_~XO=@Jnl .aBn0.nl". N2n(*H?NLTORn`.?< NLTO.?< NLTONPNPJ@g`Sn`h.NJ.NJ>NQN^NuNV&>/?`>NQNPJ@g&NYr0.nm NU\=@` NU\=@0.nm JnoJnm0.nm0.nl . a^`.?.?./<aPO.?./<a&\OJng>0.nR@=@0.nl >NQ`>0.WNQ>N[.NL|>NQN.*BW?.N1FTON^NuNVNC =@NC=@NP8J@fp`h./<NFXONI>NJB=@>?.NCTO <2.HЁ @f``09yl0Ry0y"|60H=@ n g n g``a NC>a v?NCTON^NuNV09|=@a >NQNPJ@gNYrNU\=@Jyo*0.ym0.nn0.yR@=@`NUj?NU\| _oNNUj||lp` NUj|3NU\yR@=@>?<?9NV,XO`LNU\||lp` NU\|3NU\yR@=@>?<?9NV,XOa d3 >a 8?NCTON^NuNV ymB@`=y309yfdNC ?a_lTa?NC _=@09n30.SnJ@o09Hм6 @ Ry`3=y0.yo$ <62.HЁ @2n6Sn` <629HЁ @ RyRy>?9SW/<6N@\O>/<6N@xXO=@ nOo09yfJyTgv09S@=@Jnm2 <62.HЁ @  g <62.HЁ @  gSn`Jnla"3B@`60.R@3a"a*p`` nOoa3`aB@N^NuNVNP J@g`0aNYr>/<6N_~XO=@NP>0.W <62.HЁ/N_~XO=@0.n|o>/<6N_~XO`N.a X-@. /.NMhXOB@N^NuNVNU\=@J94f .a`D.4NMFJ@f .a`(.NG\.4NoNW>NQN^NuNVNU\=@J94f .a`F.4NMF|f .a`(.NG\.4NoNW>NQN^NuNV>/]?<}/Y?</U/.a (|f`>BgBg?.?.aPON^NuNVX.NG\.6N~.6NFJ@f`Jn g.NG\.lN~NU\=@j>NQNPJ@gNYrNU\=@hNU\=@=n f.6NF=@b .^6fp`B@=@` N2nb ($5fp`B@=@^ N2nb^B(60.`n^nbBnd.NG\0.n n0.n na D|f`>b?.^?.`/d?.?. /l/6a=@\ n\f``Jn\fNU\=@j.NG\NVJ@g Jnf`B`NQ=|=nh `Rn>NQ`2 nadfN.*BW?.jN1FTO`` n lp`0. =@ 0.n ma <|f`>b?.^?.`/d?.?. /l/6a=@\ n\f``Jn\f NU\=@jNU\|f Jnf`N`HNU\|f. nf&Bn>}NQNYrNg 0.| `0.|yfp``B@N^NuNVBW/.NA,XONBbN^NuNV.a-@.a-@ n 0 n0 n0 nJfB@`. /.NMXOJ@f.ap`.a-@.a-@ nJfB@`j./.NMXOJ@f.adp`F.aD-@.a^-@ nJfB@`&./.NMXOJ@f.a"p``B@N^NuNV nJg n  gR` .N^NuNV n  fR` .N^NuNVNI4=@ nfB@`pN^NuNVNI4=@ ng n lp`B@N^NuNV n Jg@ n H"nHAf R R` n ?f nJg R R`B@``pN^NuNVBn0.nl0.HЮ @"nRRn`-n-n nHRJgR` nJg no.ap` n ?g0.HЮ @"nRRn` n ?g" nJf.%ap`~RR`0.HЮ @"nRRnRR`h nJg0 nm .Ba8p`00.HЮ @"nRRn` . 2.HЁ @B0.N^NuNVNC =@NC=@./<UNFXONI>?.NCTON^NuNVaLaa ByN^NuNVByNC>BgNCTON^NuNVJyfNP J@fa Da`Syo*0y"|6Yr0.n33a3a"NPN[aJ@f*a NC>SWNC ?NCTONYra`TNYrNU\3>Bg/<6N@\O>Bg/<6N@\ONC>a?NCTON^NuNV09yf`3=|=| 09nylx0n"|64y0H. f40n"|0H|g. H0@"|0H|f`&` 0n"|64y0H=@Rn`x09n=@0.yl*0.nHм6 @"<64.H҂"ARn`09n3aN^NuNVNC ?a_l*NC>NC S@lBg` NC ?SWNCTO`$JygSyNC>a?NCTON^NuNVNPJ@g>/<6N`XOaNPBW/<6N`XOapaN^NuNVaBW/<6N`XOaLaN^NuNVNC ?a_l2NC>NC R@|Oo?<O` NC ?RWNCTO`NC ?aְ_oNC>a?NCTO`^09yl"RyaNC>a?NCTO`.NC>NC R@|Oo?<O` NC ?RWNCTON^NuNVByNPJ@g>/<6N`XO`>/<6NWfXO=y=y3ByaBy0.nl,09Hм6 @2.HҼ600y o`,0n "|>0n "n0H?aTORn `NDN^NuNVBn nH@RJ@gN . f`D>.H?a:TO=@0.nn y o`>.H?aJTO0.n`N^NuNV . f092. HHAA`` . lp``pN^NuNV . f&> ?< aTO=@0.SnJ@o> a0``( . l>^a. H>W@a` . H>aN^NuNV y f. H>NJd`. H>NC^N^NuNV y f> NJd> NJd`b yRf*>BgNCTOND2>BgNCTONC`.>BgNCTO> NJB> NJBNDNDN^NuNV nlp`0.3N^NuNV09N^NuNV09N^NuNVBy3.ByByR33VByTN^NuNV. H>NJBRy. HN^NuNV33 >NJB>=NJB> W NJB>W NJBN^NuNVBn nl>BgaTOaRn`BWBgaTON^NuNV>Bga|TOaN^NuNV>NJB>TNJBN^NuNVN^NuNVN^NuNV>Bga:TO> NJBN^NuNVN^NuNV3By3v3N^NuNV3N^NuNV3N^NuNV yf`*NC =@NC=@>a>?.NCTON^NufB@`$`" nfp`` . 2.HЁ @pN^NuNV0.@>/. ?.N\O2.AAgp`0.N^NuNV>/.NXOJ@fp`B@N^NuNVBn nlJ .2.HЁ @Jg8 .2.HЁ @  g$ . 2.HЁ @".4.H҂"ARn` . 2.HЁ @BN^NuNV nHHм @fB@``/. /.NXO _0pN^NuNV> /?.aT\O=@Bn0.nl0n6H>NJBRn`=n0.n @RnDl > NJB`N^NuNVJnl0.D@`0.=@ n B=|0.nl:0.H H@|02.HҮ "ARn0.H =@Jnf``0.nlJnl0.HЮ @-Rn0.S@=@SnBn0.nlN0n"n 0H=@ . 2.HЁ @". 4.H҂"A0.". 4.H҂"ASnRn`0.N^NuNVNC =@NC=@./<NFXONI>?.NCTON^NuNVNC =@NC=@./<NFXONI>?.NCTON^NuNV09JynB@`pN^NuNV yJgB@`pN^NuNV09ZN^NuNVBn0.ylR0.@Hм\ @-P n0 n1| nBh n1| n1n n1|Rn`N^NuNVaNJ@g` ` RyJaN^NuNV yXg >XN"ARnRy`3ByNP>/<6N`XOaa,N^NuNV09yf`RyJyf=| `0y"|60HngB@`p09ylj0y"|60H. f40n"|0H|g. H0@"|0H|f` `0y"|60H=@Ry`aNC>a?NCTON^NuNVNC =@aNP J@g`TNYra>aB3aJ@gNU\>a>?.NCTO`NC>SW?.NCTON^NuNVN[NPJ@g$aJ@gNYrNU\3aa`6NPJ@g$afNC>SWBgNCTONYra`aBaN^NuNV>/<6N@xXO|OoSy`N^NuNVNC|gB@`pN^NuNVNC|gB@`pN^NuNV>Bg/<6N@\O>09S@lBg`?9SW/<6N@\ONC>a?NCTON^NuNV>/<6N@xXON^NuNVByBy>/<6N_~XO=@ no.VNO|3`3>Bg/<6N@\ON^NuNVJyf`:ByNPJ@g>/<6N`XO`>/<6NWfXON^NuNVBy09yl&>/<6N@xXOnlRy```09N^NuNV3 yRf.>BgNCNV yfBWBgNCTONC yf2BWBgNCTOBW/<fNA,XO>NU\?NNTO`0NU\yg"BW?<NCTO>NU\?NNTONU\3 yVf< yf2BW?< NCTO> /<mNA,XO>?.NNTO`4 yVf*0.ygBW?<NCTO>?.NNTO3 yg yfnBW?<NCTOJ94f>/<vNA,XO`D>/<4NA,XOBn.4NF?p_noBW/<NA,XORn`By yg yvf&BW?<)NCTO>)/<NA,XONDByvByN^NuNV3NC >aBW?<)NCTONDNC >/<NA,XONC >/.NA,XONC >/<NA,XONC >/. NA,XO3vN^NuNV./.NXOJ@g ./<N"XO3vBWaaN^NuNV3N^NuNV.NF|)N^NuNVA-H nBP.?<?NuZTO n-h n ("n")Ё# n (#ByByByByN^NuNV 92.HЁd(0.Hѹ>Nj 92.H``BN^NuNVJnn`v`r . c4Bn0.nl$ . 2.HЁ @".4.H҂"ARn``40.S@=@Jnm$ . Lj3X.NL|N^NuNV=yJ09R@no0.`09R@3J yJlp`09J3J09Jn=@Jnf`` nf a``` nf a``JnoR09n@nyJl2>LNm4#09R@"y2)A3PaB`<`a`4`20.@yJo">Nm4#3Pa``aN^NuNV g2 yPm(09Pyn yJm09R@yJl .Nqr09PyJoT y=P nf .Nqr>Nm4# y0(yPJyPn .Nqr`N^NuNVa0J@g` g@09PyPm2 yPm(09Pyn yJm09R@yJl .Nqr y0(yPyJnP y0(yP y=h ng09Pyo .Nqr>Nm4#`N^NuNV3XBn ndl0>NH:-@Jf`0.@Hм\ @ Rn`3 yl.NO|N~.NMFJ@f aX`4`4>/<NLRXO3X yXf.NO|N~#\.?9XNLTOBy 9\-@.N=@.ZN3L. N3.N3.NTOND2>?<?.WNV,XO`J y.f&ND:>?<?.WNV,XOND`>?<?.NV,XONDN^NuNV3 yf*>BgNCTOND*>?<?.NV,XO`F yf"NDX>?<?.NV,XOND`>?<?.NV,XONDN^NuNVa8J@g&NU\>Wa>a?NCTO` yf6NC=@>RWBgNCTOND*>RWaj?NCTO`>NC=@>0.W?.RWNU\?NV,XO>RWa*?NCTON^NuNV yf$NC=@ND*>a?NCTO`bapJ@g NU\>a~>a?NCTO`:NC=@>0.W?.NU\?NV,XO>a?NCTON^NuNVNC=@ yRf*ND2>?<NU\?W0.WNV,XO`VaJ@g0NU\>aD>?<NU\?W0.WNV,XO`>0.W?.NU\?NV,XO>BgNCTON^NuNV nf3 3P `By 3O N^NuNVBy=n 0.nlV0.R@@Hм/0n"|?00n"n0H?aHXO2.AHҼ"A2A _0Rn`N^NuNV0n "|00N^NuNV0n "|00y m`zNC>0n "|?0NCTO0. nlH0n RH"|2.HЁ @".4.H҂"ASn`N^NuNV33 Jn lB@`0. 3N^NuNV>?<NuNTOJ@g>?<NuNTO|=@`BnJng*3By0.29HҼ"ARyJyoSy0y"|0H``pN^NuNVaj=@|f. yf"Jyo>?9?9NV,XO`0.N^NuNV yf$Jyo>?9?9NV,XO`N^NuNV. H>?<NuNTO. HN^NuNV. H>?<NuNTO. HN^NuNV./.N}0XON^NuNV./.N}0XON^NuNV.N~N^NuNV.?<NTO.NFN^NuNV.N=@ nfp`0.|N^NuNVBn.a=@ n f`` ng nfP0.U@no0.`0.U@HЮ @ 0.S@no0.`0.S@HЮ @Bp`` n fN0.U@no0.`0.U@HЮ @ 0.S@no0.`0.S@HЮ @B0.`.`(0.U@no0.2.HҮ "ARn`Rn`N^NuNV. . H?NTON^NuNV>/.NXON^NuNV> /.NXON^NuNV>NN^NuNV.NDN^NuNVN^NuNVBW0. Hr /?.N\O|fp`B@N^NuNV>/. ?.N\O=@ n32./<4N"XO3 ng.6NO|N~ap3P3JBWNm4N[3ZByN^NuNV09JN^NuNV09N^NuNVa#\ByByLByBy yBh y1| yXg >XNLj3X.RNL|323JBy3PByZByN^NuNV09JylB@`pN^NuNVNC =@NC=@=yJJn oB> BgNCTORn >aFRnSn yf> ?. ?.NIXO``>?.NCTO>aVN^NuNV0>aFJyf ngJyo&09R@nfBW/<_NA,XOND`h0.yoND`T>/6N_~XO=@4 n4l0.4`0<=@4 N2n4| 6BW/6NA,XONDN^NuNVaJ@g> /.N`XO` >N\ > /.N`XONb(N^NuNVNl>XNLj3X. H>/<NLXON^NuNVByZN^NuNV, yXf Nf3X>aBn n-l N2n| 0Rn`>-/0N`XOA0-H>/.?<NN|\O=@ .2.HЁ @B>/.Z?9LNN|\O=@ n2nB(>/. ?9NN|\O=@ n2nB( >/.?9NNNu<$/*NNu%jP%jT*SG<g&jT"jPPT`Nuap*dG<%Kja(G<%KraGX%K^aBG*OB<ܼ^%thZaG`%KZatJgn&j+<ASGXa,|:Xa"| * b@BG*&j3p<F< g * f |.XajXa*dB*a.m<,O`Nu|BaNu*9*f*8*f*7*fp`pNuaZGb%KC<%I|%aGd%KCE%I|azG<%KradG<%K~a *f|G<%KaB*\|NuaG%Kfa*?F* d| *f| G%Ka4*<G*<G*<G*<G*<G* <GG%Ka@G7%KC%I|aB*6B*7B*8B*95|Nu*Fda>*|5GJGgBja>*&|.\Cp%Iba**Gd&G<%Ka<f |G<%Ka8` G<%Ka>*jdB>*&|.\Cp%Iba$G<%KzaJ*g|G<%Kaj`*CdBjG-%Kba>*jdG<%Ka0JWGj^B* *U*d.BG*,j&|-3`"|.\1pWD*`j5@a@J*g*a@`aJg| G%Kaa@`NuJ*@c| BaJ*>c| BaNu*<Jg |a`aaa2G<%Kja *f|G<%KaGb%Kfa *gGb%Kja*kdd*DFdZ *Yg& *NgGh%K^a"a@a@` *Yg G%K^aaG<%Kra`a*k*lGb%KaGb%KraGb%KCL%I|aG<%Ka*c<*Gc*d<*Gd*e<*Ge*f<*Gf*j*k<*Gk*l<*Gl*mGb%Kar*.da*!B*"G%KaPNuG.\%K .*-oG%K^aazB*.*-l *d*`G.\%KP.*P |N%@TЪP%@.*P|O|5G5G *Fd2G.\%K j@ e5| 5|`$>* j5G 5G`>*j eaBjNu**|5G B* *b$BG*j &j 3pf5G`*dNu`a`G%KaG-%Kba~dzG%Ka>@Jf5j8^j7]B*`T *f>*8RG5G8JGf*7` *f>*8||5G8JGf*7`B*GN|\O=@ n2nB(>/.?92NN|\O=@ n2nB(.4/.N"XO>-/9\/0NHPONl>XNLjN^NuNVaJ@g` ` SyJaN^NuNV n0N^NuNV n0 N^NuNV>/9aXON^NuNV .м2. RAAH.aN^NuNV> ?./9a\ON^NuNV> .м2. RAAH/a|XON^NuNV>/9aXON^NuNVJn m n0(n n .NqrNPJ@gB@`<`:Jn f> /.a@XO`$`"> SW/.a,XO??. /.a\O_N^NuNV>/9aXON^NuNVJn m n0(n n .NqrJn f .\``> SW/.aXOHЮ\N^NuNV>/9aXON^NuNVJn m n0(n n .NqrJn fB@``> SW/.aZXON^NuNV y0(N^NuNV n0(N^NuNV.aN^NuNV nJhf0<`*`( n>SW/.aXO?0<_"n2)AAN^NuNV>aa6N^NuNV>aa$N^NuNVJnoNPJ@f.Ng3Z y=h09JyP=@Jnf(0.nm>ar0.n.Nq`R0.nnn.>0.W?.aTO0.nn.Nq`>ap.Nq``:N^NuNV y*Fd|G<%Ka8`tG<%Kza>*&|.\Cp%IG.\%K<*G5FFaNuap5j>*jd>*&jCp%Ibaj"G%KvaJ*g| *gB*G%Ka*"*g *6fB*6G%Ka2ahF@*F*d|G%KaP|>*&jp` j`DNu * e*J*1c **1b*2d<BG*?NtBG*G<3pN`*N&Z`t<BG*?Nt``<BG*?Nt`L<BG*?Nt`8>*j ea>*&|.\pj`<BG*?NtNu * g ja `PJ*Af ja`>j**Ae *A*`*A*GJ*c*| a` * fB*NuJ*W*HGHd| ` *<0GafNu*Ga*<GaNu| *;WGH*K*DGK*J|GJ*I|GIjIajJajKa *;f|:a| `| aNu*3d * gz*dN * gFj=J*=g, *f|<*RG*eB*| avJ*;ca&B* * fB*jaR * f|Nu *ae *zb*_*Nu *Ae *Zb* *Nu|BG*;G%KaL`Nu**GB*B*B*B* *b\BG*B<*ڼ.J2Xg<ܼ 4hfB*`(BG*B<ܼ 4hf**GB**da*daD*dj*Fda*F*d*a G%Kja*daD5j*ej5ja5j**dab`*5*6dal`a8Fd ja`**d5j` *daNu`a| * b8BG*rpb 2 pbg * f |.Xa^jXaT*dNu*.Fdp`la|?"G%Kna *gLG-%KL*<RBݪL%jLG%K|a*!Fdp`a`pNuBjBj~d0aG-%Kba(B9-G-%KnaBj *g>*оjd ja` *f.Jjf| G-%Ka*8Fda^`>*RG5GG-%KL*<RBݪL%jLGc%K|a(Gc%KC%I|aadB*nB*"*lF*?d*8FdJjf G%K^aajB*a `Nu**:f*b*faNu*+RG+*ep `BG*+B<ܼrha Nua@< gNua * gajNu`B*BG*ݾ| b B<*ܼľ4hfp` *`!dN#.T#.X y.X3-A8C-0<GQ y.XAC-0<QK,M,O,IE&dNBB2//NB _ONB"//NB _ONCOPYRIGHT 1982DIGITAL RESEARCH0102821100654321ACڑC+I,A&dCC+I(+O<``>*je**F*dBj` jg af5ja>*&jspj`6B*<BgNt@` <BgNt<@` N&V@*dT*<d*RGJWF` * WG*d$azda<fp`H|Ba\*Gd**Bd ja`*9d ja`*Nu`d**G|B<*ڼrXܼ 2hfBG*B<ܼhp`**f*`B*pNuJ*c*SG<fp `p`~dJ*c(*BG*B<ܼrh**`fa@<fp`TJ*@c(j@a$dj@B*@*RGB*`J*>cj>adB*>|p `*Nua@*<d>*jR* ` *W Nu`*<0< b `.*<A<c| G%Ka*<A< Nuad@@aNaNuNVa@aހ.*@N^NuNVa|H=@a|nN^NuB*a@~d *:g8 *f*e|G%Kajaa@`a@a@ja@a*J*f|`B***6d *:gj *g`af@`|:aLjaBja8jadpNu*BG*&jp *?f|Nu|?**da`Nua<@ * W *]WƎFd*<AG߾<c" * f a@`|Ba` *Sg *Qf0*+RGa@<Wǰ< WƎFea@`La@<0@< c|`.a@<0@۰< bBG* BF*FG`BG*B<ܼ.h *f *c|Ba&jj$`a@Nu&j| %| B* *#d * fB*aj`*R&jG&jj,$B* *bBG*B<ܼ.B2h*dB*B*B*a~dB*jaFd, *d **f |a`aaP@` *:f *fN&j+<ARG<bLaJjabd *[fa*+&j| %` *f|B* * bB**RG<b&,*||B:&jڼ4X3`g *f"&jj%a|<[fa4*+`**d` *[fa `J*gj| *.f8a,@@arFd" * d> **f | a`a` *[fa*+&j|%&jB+ Nu(|$^N.m<,O(|$^$|&dG-%KC%I|a2J*WGaj|"dGFBG*&jB3p HFp*dNu&jB+B+ކB+ކ%G%|B@|JgB*BG* *,*N^p$ *.*N %@ *~ NV%@`jaNuG$%KzB*~5|aLG+%KzB*~5|a6&j5ka&jkB* *b>*d$BG*OB<ܼ,%thG+%Ka*G*dG+%KC$%IarjaNu&j>+OBF+|z nF7G&j+GNu<N(0~&j<+nF<N(0&j>+o7GNu*<AGJa|:JaNuaaNuG%KLaBG*5G5|daNu&j>*SNuG%K`a<.BG*?Nt *~NVNu`:a%j|a\|:JaXahNu&jB+&j7jaNuG%KG%KRaaLG%KLaL&jB+<N(`R@&j7@%jaazG%KLaG%KLa %jataTG%KLa<N(`R@5@aXG(%KLaGR%KLa< N(`H5@a,G0%KLaGR%KLa<N(0R|H5@aG%KLarG8%KLaf<N(0~o5GaG%KLaDGL%KLa8B'N(`5@aG%KLaGV%KLa<N(`5@azG`%KLaadNua^%K^a&a*dG%K^aaaj@,a@@~dB*KB*JB*IB*B*BjBjB*B*B*|||||*d|*Xa^aap|+ *baa&Gb%Ka*d|Gb%Ka|a *=g *_gaDG%Ka * fh *;ga$aaN|*d$G%KC-%I|$aa`|G%KCc%I|#aa`Z *f8 * ;f0a>a|;Gc%KC%I|#ava` *c|Ba` *gB**da *,g * g|BaV *,WG* *f|;J*Af|AJ*=f|= *;U * ;RƎ*d|Ba *;gB* *;fB*~<'b*B*a*d` * ;f |a`aa*d G%Ka`j`hNuERROR: $ - $$$$DESTINATION IS R/O, DELETE (Y/N)?$**NOT DELETED**$**NO MEMORY SPACE**$COPYING -$REQUIRES CP/M-86$CP/M-68K PIP VERSION 1.0$"6Jp`v (7/31/82) CP/M-68K PIP VERS 1.0 DISK READ$DISK WRITE$VERIFY$INVALID DESTINATION$INVALID SOURCE$USER ABORTED$BAD PARAMETER$INVALID USE`#NBN#8f#8j y8j37A8C70<GQ y8jAC70<QK7 M7 O7 IdE(NBB2//NB _ONB"//NB _ONCOPYRIGHT 1983DIGITAL RESEARCH0102821015-0272-654321AdCC+I,A(CC+I(+O<&j>Jg&j>SJa>`Nu<BgNtNu<BG*P?NtNu< BgNtNuad<BgNtG%KLaaNNu| JaN| JaDaNua%jRLahNu< BgNtNu<BgNtNua5@jV<BG*V?NtNu</*XN@Nu</*\N@Nu<BgNt@Nu<BgNaGr%KLajaa@aGz%KLaB*BG*ؾ|bB<ܼB2h*dG8n%K`aG%K\af *gJ*<|&|8nsp&|8n 3pg*<|B<ܼha*`B*BG*ؾ|b*B<*ڼ2Xd5G5|da*da`Nua5@B*Jjg"*djpaa*`NuB*B*|**bT|B* *b,BG*BF*&j3p2`gB***d*d*` *dpNu`%j>&j> :g&j>SJa>`|:JaNua,@B*arB* *bn*|B<ܼGh%KaG%KLa*<*|B<ܼHGh%Kab**Ga*dNuG%KRaaG%KRaG%KRaGf%KLaLG%KLa@G%KRaG%KRaG%KRaB* *b|a*|B<ܼGh%KaG%KLaB* * b6| Ja**|B<ܼHGh%Kaj*d*d~aNuB*G%K|a@JfJ*fp`* *faF` *fa` *faF` *fa:`*SGGahFeBG*B<ܼHGh%KR NUMBER$INVALID FORMAT$HEX RECORD CHECKSUM$FILE NOT FOUND$START NOT FOUND$QUIT NOT FOUND$INVALID HEX DIGIT$CLOSE FILE$UNEXPECTED END OF HEX FILE$INVALID SEPARATOR$NO DIRECTORY SPACE$INVALID FORMAT WITH SPARCE FILE$$$$$$$$$$$%%%/%>%P%[%v%% =.:;,<> _[]OUTPRNLSTAXOCONAXIINPNULEOFNqNuNqNuNqNuNq _ON$$tNu</*`NNu<BgNtNu<BgNtNu</*dNNu< ?<NtNu< BG*h?NtNu<#/*jNNu<.BG*n?NtNuN(<N(0W@o<d5|`<N(0W~o5GNujpVaaNu%jrB%jvF*qSGq<g&jF"jBBF`Nu%jz>>*SG5G|g&j>~>`Nu` *d BG*p*NuBG*#&|7sp&|7 3 pf*#` *[f*#B*G%Kz| ~5|ahBG*#&|7sp&|7 3pcr *!e *,g *:g *[g *=fBG*#&|7p`*# */g *$g *]g *,g~ja`pJ*g*#Nua *=gp`a<Nua * fa * fp`<Nu|JjgZB>*GB>*HG5GB>* 5GJGV*d J*fa`B**<0GJa`Nu5|'|Jjg:*BG*B<*p$B>*HG5GB>* 5G`Nu`8BG*J2p$f*dJ*g*dah`jJaHB*Nu||*SG<g.BG*2p$<0Fa *g *f|,a`NuB*B* *bXBG*&j"j3p1p*pBG*&jB3p |a.S@<gV|*SG<g*G*G`a**@@PaaFd<`G%KRa<Nu*d$G%K`avjnaG%Ka` B*a`5@G%Kja|KJaNuaa|RJaJ*g>**o5G`5j*d|OJ`|WJaG %KLa|aNNua5@B*Jjg"*djpanaz*`aNu` a* 0SG 0<g |-Ja$`Nua(| 6 * 6b4 * 6f |.JaBG* 6&j 23p<FJa* 6dNuBG* 8&j 3pd<`pNuj 9 8ad j :Ja`aNu* ,d"&j <>| o<|NF5G @&j <>O`&j <|5G @&j * B<.F D>* @* D&|8n3p* DfP*3d B*3G%KRaaG,%KRaa&jSa|Ka%j 2ap`>* @* D&|8n3p<Nu| J * Jb:BG* J&j F 3?pg &j F3p<&j3p<gp` * Jd<Nu| M| L* L* 'G L<T* Md`BG* L&jsp (* ,dBG* L&j3p* (J* (g* KdBG* L&jCp%I *S`Nu *gTG7%K*Bݪ&j  d,|a &j B+%j daj `NuaH@dJ* .g,<N(`^@H5@ ||fj G8n%KB>* ߪG8n%KzB*~5j a| '<N(`|RG ,d| 'Bj B97?7?7G%K\aa *gHG7%K>*<Bݪ>%j>a* -dj `aabaa`*3FdazJj fG%KRa6`*FdaaHa~`aHNu5| TJ*g ~*o5G T<%?* TNtNu`(G%KRaa&G%KLaB%j XLa8NuG%K|at@ V<faTG%K Xa`N * Vf"axJgG%KRa|`0G%%K Xa`$G%KRabGv%KRaVG%KLaNuG%K|a@ \<fa` * \fa`aNuB* B*|#B*2 *2bBG*2B2p$BG*2B2p+*2d|2|3Bj4Bj6Bj8Bj:B*N# f. N0N+9gR 9м#0.SnJ@n."NqhN,f~3Sno n 2G 0 @ -f n 2G p(HRG`ZRyd`hRyj``Ry`XRy`PBy`H0@HЮ @#RG`20@HЮ @#6RG``V`H |r W h$N`V./<|N,XO./<|N,XO.|NHм|S#.6/<N,XO.(/<N,XOFlBWBg n 2G/0Ny6\O30@HЮ @# n 2G.N0>/<:N-4XO3N-3 yzN-3 yN-3 yN-3P yJydgn#3,BG|~nh0@Hм2AHҼ"A"0R@@Hм @ 0@Hм2AHҼ"A"0R@@Hм @ TG`BW/<`N(XO>/<N(XO> KaFG7%K Fad&j<*ga`Nu>* OB<ܪ%F ܼ %F .* ޼%G .* ޼ %G Nu`>G%KRaGv%KRaGf%KLaXGH%KLaLG%KLa@NuaFdp`h *=fatG%K|ab@ .<f | p`6J* .faz`&ahdG%K|a(@ /JfaR<NuBG* OG<3pN`&j + G%KLa`T&j + G%%KLa`<&j + G5%KLal`$&j + GB%KLaT` G%KRaNuB* -Bj * -Fd$>* j dan%j  Fa0@ -j `Nu5j j aF j b.* ޼7mGP%KRada>* OB<ܼ5 hB* & * &bBG* &&j "jpp* &d>* O&j BS&j BSB<ܼBrhNuNV&j +d| & * &b*BG* &&j3p<<f &j 3p* &d&j+ <<g &j + &j Sj6>* O&jBF+B:(ؼrH<-E=F=GN(0&j+ |HnB>.,޼5xB* Ka`&j + d&j j8N^Nu j c$5| Jj caBj Bj $>* UGj $e>* $OB<ܼ5rh a|%j >* $OB<ܼ5rh a\| & * &bBG* &&j3p<F )BG*ED TRACKSACTIVE ACTIVE FILES: IS STAT 2.2READ ONLY DISK: D:=ROSET ATTRIBUTE: DISK STATUS : DSK: D:DSK:USER STATUS : USR: D:USR:IOBYTE ASSIGN: =, FREE SPACE: BAD DIRECTORY ON SPACE ALLOCATION CONFLICT:[SIZE] TOO MANY FILES SIZE RECS BYTES FCBS ATTRIBUTES NAMESYSDIRTOTAL:, FILE NOT FOUNDDISK RESET DENIEDD:=ROERROR-READ ONLY STATUS NOT ALLOWED2Jb????????????? DRIVE READ ONLY (RO)READ WRITE (RW)SYSTEM (SYS)DIRECTORY (DIR) DIRECTORY ENTRIESD:FILENAME.TYP USE: STAT INVALID ASSIGNMENT SET TO 128 BYTE RECORD[RO] [RW] [SYS] OR [DIR]CON:AXI:AXO:LST:DEV:VAL:USR:DSK:RO RW SYS DIR SIZE  'x''''''TTY:CRT:BAT:UC1:TTY:PTR:UR1:UR2:TTY:PTP:UP1:UP2:TTY:CRT:LPT:UL1:`p NuNVH(|($|2@pPLN^NuNVH(|($|2@BG.2pLN^ _ONNVH(|($|2@BG.BF2pNBE2pF LN^ _ONNVH(|($|2@G%K</ N<abR@LN^Nu/<eN(XO>/<kN(XO>/<N(XO>/<qN(XO>/<vN(XO> /<zN(XO> /<N(XO> /<N(XO> /<N(XO> /<N(XO>/<N(XO`N. 3B3h3ByByN)v3Jydf./<N)BXO.N'#./<N)BXO.N'#Z./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#F./<N)BXO.N'#v./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#J./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'# &&j 3p<E *dZ>* $OB<ܼ5rh ">* $OB<*(ؼڼ5HX>* $OB<ܼ5 "hj | &`* )* *c| &* &dTj $d`NuB* QB* RN(<0RG Pd| Q* d | R* QG%KRaa* Q<GKaja* dG`%KRah`aJGl%KLa* Pd G%KLaG%KLaBj >* j d>* OB<ܼ5rh aa|q&j C%IrG7%KvaFB97* d&G7%KjaG7%K|ala>* OB<ܼ5rh5|'aa>* OB<ܼ>2hOj4>* OB<ܼ>2h|JGgj4&j 5S5|'aP&j >j:|KJala|| 8a@ +&j &j 5S5|aaP| 8a\dG`G%KLaPa,|RJa| 8a.d|OJ`|WJaa* Pdl* +d |XJa`a| 9|A :a| 9|1 :a| 9|2 :a| 9|3 :a| 9|4 :aa%j  2aNj `* Q<'G 0aG%KRaj RKaZ5j:5|'a|KJa"5j65|'aNuBj >* j dl5j ava%j  2aG%KLa* .SG Oa@J* /gG%KLa* /SG O :$$ ./<N)BXO.N'#^./<N)BXO.N'#R./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#./<N)BXO.N'#a JLN^NuNVHJyg09hybmBGBya`#ZaJLN^NuNVJ9f>N+~`N-.N'#హg>N+~`N(t.74N1< yfJm o >N+~`b 9؀"yi y,g > N+~`6.74N1< yg >N+~` y!yN+N^NuNVJ9f>N+~`rN-.N'#హg 9~f#N(t`N(t y(g>N+~` yh33.74N1N+~`Jydg yh y!y yf yh`X yf yh`@ yf yh`( y,fN)v3|rf yhN+N^NuNV>aN^NuNVaa (09@Hм @ 30.@Hм @#fN)v3 ybg yBf833bRy3N)v3N+``d ywg yWf33w``< ylg yLf33l``09$3. 9f33l`3w3N^NuNVH~09D`TG>a @BWa@`JyVgTG>a@`TG` yfR 9f*9`$ 9f*y-g*-`` `` 9Tn lvTG`p ylfp`p@>ab@`PJyVg ylfp`p@>a<@`, yffBWaf@``S@|b@0@( PN0JL N^NuNVH0n"|VJpg ylfp`p`>a JLN^NuNV0n"|Jpg.0n"|lJpf0n"|Jpgp`T`B@`N0n"|Jpf0n"|lJpg(Jyg0.@Hмl @ Pfp``p`B@N^NuNVHJ9g./<N)BXO.N'# 9హg` 9~f#N(t`B y(g>N*B` y(g>N*B`f`N(t yh yf yh`$ yf yh` yh y!y`BJLa3`a`J@gܰ|gl|g`JL0N^NuNVH y'g y"f09Jyf yfP y#fFH>avJ@g(a 3Hyg>aa3Jygp`2B@`.H>a0J@g 3#,ByN`B@JLN^NuNVH>.BFzBa3gyfat3ygBE`` y f >aXBE`J 29H(RF0ym*a,3Gfa3BE` 09$``vylRF`3#ByJyfN0JLN^NuNVH nf~`& nf~` nf~`.a aBa3<9|0m |9n|0`&|am |fn|`|Am |Fn|``JFmnl 22HЁ*```#3ByJLN^NuNVH*n BBGnlB n H<R |0m |9n|0JFm| mB@` "Ё2HЁ*RG` n pJL N^NuNVHa\@HЮ# y*h f*y` y P!y (M&y~JGgLg*m `SG` JL8N^NuNVHBF*yBG|l H@RG`0|~JL N^NuNV y yJf y!y 9e4>Nΰf.aa`yN!b09N*N+N^NuNV>aN^NuNV>aN^NuNV39g >ab`N+N^NuNVN! yg>N+~`.N'#హfN(t` y(g >N* yh  y(g yhw y,fN)v3`N+```N^NuNVN! yg>N+~`.N'#హfN(t`& y(g y(f >N* yh.aZ y,f:N)v3N! yg >N+~`$ 9"y3@` y1|N+N^NuNV ym.N0N,f 9"n3@ y XRyN^NuNVHBN!bJyga 09N*BG|l BWN*dRG`JydgN/L.NqhN,fN)v3g .9N009@Hм @ NfJyfN9N=$JLN^NuNVaN!bByp.74N1< yg >N+~`\Jyg > N+~`HJypgRya T09N*09H//9NPOѹN+N^NuNVH yo>9g4*y#N!b09N*#RJL N^NuNVa>aN^NuNVaN^NuNVHBGByRyfByj3" y'g y"fBGN! yf yDf yBhfaa< yf" y,fJGg >N*RGN+`BG f yg y fN)v3``VJyjgH yff*JyXf"JyfJynfJyf ydm#^#^JGg >N*JLN^NuNVH yfV.N'*@g@-g8 m.#N!ba&3#,a3JL N^NuNVHBy yfZ y,fJy&fRyfJyfRy y f y gN)v3``d y gX`3 ym.]N0N+09"y yf.N'*@ y!MfN(tRy\-f(0y"|0029AHҼ"ARQ` -29AHҼb"A2``l yfbJyg" yg09@Hмl @0`,09@Hмl @JPf09@Hмl @0 yffa4 y!y09"y@Ry\JL N^NuNVH y,fJyVg.9 yg* yf 9f y-f D.*y^f@Jyg yfm"ndN^NuNVH./.a@XO.a*@g>aav`aLm0n +HJL N^NuNVH *n(n ~Jg JGgSG`JGgBSG`JL0N^NuNVHJ9$g9$HB9$`TJyn4>/<?9Nz|\O3JynB@`H# yH>RSy|g| fJyfRyh`| f~ 0JLN^NuNVHJ9gal*|9H|0SGJ@gBF|l>aRF``JL N^NuNVH 9ܰe <d.Nqha <b6>/<?9N~\O|g. aa# y0TJLN^NuNVHJyg*0nSH"|.?9/<&Nqh\O`> y f >9hSG`>9h0nSH"|.?/<1Nqh\ORyJLN^NuNV>anJyfa N^NuNV.;aRyaN^NuNV y gJyg a3`a3 y f a3`N^NuNV y f al3`N^NuNVJyg, y f aF3` y f a03aN^NuNV3aN^NuNV yz.|N y.|N y.|N y.|N ygJylg > NN!bByfa09N*09fѹN^NuNVH yfJgRy.74N1<09ygJyg >N+~`N 9ذl >(N+~`4#N!ba09N*#aJLN^NuNVHByVByXByByBylBynByByBybBydBy&ByfByBy y fN)v3`` y f6 y fN)v3` y g09$3 JygR y*f6N)v3 y=fN)v3alN+By` 3wN+3N!By y:g y=f yg>N*B9`.(y*|d:` y:f N)v3N,Jyg y*fN+`N! y:g y=f*J9gN1aD./<N)BXO`R`B9N+ y=g8 yf y=fa,` yg`.N'#f>N+~N+`a y(g" y (>0@Hмl @&PN` y (3h y0(|3Da`N!bJyDgab`N+ y0(|3Da6>09N*0Hй#JL8N^NuNV y.#R#RRyj`XJoo`Jgf##`$gFf#v#vJL N^NuNVB9 y g0yh#`09hS@H##09# 09 # 3#N^NuNVH y'g y"f aJ@f~BFK y mz|f y.fz`V yAm yZo( yam yzo y~g y_fz` y0m y9nBE0G@Hмn @:|g>09RFa3`X0`"B3./aRXO.a(@ .~gbJyfZ0,|P|@fL3#,g 3`*,g 3`,g 3`By`>//YaPOJ@f >ajB#3By`d09`Jy"g By"`Ryp33#`>a`>a` >a`0y"|V0029AHҼV"ARQ`40y"|0029AHҼ"ARQRy&`Sy&30y#`H |rW hN y g a3 <f y<f a3 >f y>f  kBWNkJyo$3f>/<GNqhXOBWNkJyfBW`>Nx$N^NuNVHJn g>?</.Ny\O>`>?. /.Ny6\O>JGl.Taa0JLN^NuNVH yR9>?</<|Ny\O<JFm0`.oaaJL N^NuNVH *y(|d:B\`JL0N^NuNVH>Bg/<Ny6\O>JGl./<NqhXOa">/<?Nz|\O|g`>/<?Nz|\O|f>/Y?Nz|\O|f .>/9?Nz|\O<0H".g`t0HH@J@fd0Hй#&yS*|d Jg ѕX`*|Ļd Jg ѕX`(ydJ g Ѭ `>NxVJL8N^NuNVH>?</<Ny\O>JGl./<NqhXO`&yS*|d Jg X`*|Ļd Jg X`(ydJ g `>/<?N~\O|g./<NqhXO`v>/<?N~\O|f 9<0HH@J@g`0F-H>/Y?N~\O|f>/9?N~\OFf~>NxVJL8N^NuNVBWNk3fJyjfNk.?9h/<Nqh\ON^NuNVH *n(|N^NuNV0.n f0.`"JngJn f 0.n ` >N*B@N^NuNV n f >N*0.n fB@`Jn f 0.n ` >N*B@N^NuNVJnfJn g >N*B@N^NuNVJyNg >$N*RyN n3f33BN^NuNVH?#ByjBBB9>NxV yz>?</<|Ny6\O3JylN+NdDJ@g|# y(fH y0(|3D9H3 yDf yg 9f9 H3|f9H3y09м#9H33# 9 #.7N1< 9T yfjJyNf`JygV y DfXBE m n :9UE`" 9ذm n:9YEJEg#`0 m n fz`z``Z>a0Hހ09J9f>B?9Nn\O, 99H&BW/?9Nn\OJl.N0N+>/<?9N~\O|g.N0N+BW/?9Nn\O` 9Zf``|JLN^NuNVH >.*|d@I @JN^NuNVHJ9gN+ y0(|3DBBy3 y (33## yo>JyDf > N*`* yDoN+`0yD"| 0 @NNeJ@f >N*>Ni09Hѹ09yg >&N*NmlJLN^NuNV.7N1N*BBy yfN 9ذm o >N*Ty 9"y2T yBPT`2 n l >N*09|yN^NuNVHaJ@fp*|f.aJ@gZ 9Jg 9f.aJ@g >N*.0y?5?9aXO``.aLJ@g8.aJ@g*.0y?5W?9ahXO``.a,J@g 9f #`@ 9f #`& 9f #` >N*`P y0(|3D yf >"N*`&y*|``aJ@f >N*JL N^NuNV.a>J@g.abJ@gp`B@N^NuNV.aJ@g.a9>al8JDg3|f"RyRyRF\:+y`v|f->aDmRE\8)mSF]``RF\:+y``*ByByRE\8)y3"``>JGmRE\8)m]SG`|mK@]BF0W@@n\ g -g - f.a~-@69.\al-@=y -=@0.` .Ѯ>?aTO6` .>?aTO6`/./YNzPO>?aTO6`/./YNPO>?aTO6` .>?aTO6` .>?aTO6`x2.0.-@>?apTO6`X2.0.-@>?aRTO6`:>N*B3By``H |rW h N 2Ё*@@+nCI >RGEl\\:+lRG`UE`2RF`< .@f* n?Df">N*ByB3`` .Ff .@g n?g0(T,g,g ,o0Hg(l `P`JL0N^NuNVH #Byj33#3$3&#,(33#3P|3~#3`(9gR#*9gR#.#2*|(BG|l.?NwTORG`BBBBB33>NxVBWBg/9Ny6\O3Jyl./<(NqhXON+>NxV yzBW/<|N-4XO33N)v3NdDJ@g 9309ymBG#9H3y09м#9H39H33#By3 y(g y (>0@Hм @(PN`aV`2JL0N^NuNVH09@Hм @ 9g3BWBgNlFTOR9g3BWBgNlFTORBBy> NeBWNiNmNe.$NwNm.Nw~BW??9N2XOJ@m>/<?9N~\O|g .BN0N,fJLN^NuNVBWNi yg yf^.7N1< yg > N n>|8|m |8np`B@JLN^NuNVH n>|8|8f n0||np``B@`pJLN^NuNV n0|8|gp`B@N^NuNVH n>|8|g |(g|0fp`|8f n0||np`B@JLN^NuNV>,/9NdXOJ@g \p`B@N^NuNVH*nJUm Ulp`B@JL N^NuNVH*n Um Unp`B@JL N^NuNVH*n 0.r `y0. y0y.a JL N^NuNVH*n0@|``4.a8`* n l >#N*>-|0- r `@0-r `@Jmg >N* y0T yBPTTy`0|`~.a*Bm.a`Jmg,0-yg >N*09HйBm0||g4.a``T.aR yf .aBm.a@`4`|b@0@ PN`|g|g|gN`JL N^NuNVH*n y0TJmg mg >)N* m g0- @|"y2T` y0TTyJL N^NuNV y"n0T y0TTyN^NuNVaJ@f ygJyg y fb>/<apXOJ@f>/<a\XOJ@g: y f30y"|p00| n+Jg6 n-Jf.@aD-@B``|@BFREK@IF`V.@H3 yf.@a<#`#B yf y(f`F yfx y0(|ff y(g 3`6 y(g 3` y(g 3`By y#3`8 yf" y(g.ap3` .AH3JL0N^NuNV0.`$p`8p`4Jygp`(`$Jygp``H |Dr W h,NB@N^NuNVH *n f-H3 -` g`&(m,g .aB`d,g,g>N*ByB`@,g 3`*,g 3`,g 3`By ,JL0N^NuNVJygN!Jyf.>a|f330y#`TByN! yf(.N'# 9ذfN(t` yf 0909#N^NuNV 9f*3# 09#`: yH3 y# y3#\N^NuNVH>.|0m |9nB@`^|am |znB@`L|Am |ZnB@`<|_g0|~g*|*g$|.g|@g|$g|%g |'g|"fB@`pJL*`Z09H//<NPOJgBWBgNlFTORS``09H//9NPOѹN^NuNV09@Hм @ 3#BWNiN^NuNV09@Hм @ 3#BWNiN^NuNV09@Hм @ 3#BWNiN^NuNV9g& yg yf BWBgNlFTORBWNiN^NuNV yg yf@ 9-@By>NiJoBWBgNlFTORS``#BWNiN^NuNVHBEBFBG.7N1< 9d] yg yg> N*BBy yf09f@|3 nf m lJyg>N*BByJEf* 92AHҼ"ABW?9NlFTORE`( 92F@RFBEBW?9NlFTO`6` nfj0@Hм @0RF>?9NlTO|o80@30RGJ@g >Ni` >Ni09HѹBF`,0@Hм @0RF>?9NlTO`l>NeJ@gb\NeJ@gNJEg0FB(RFJFg40@E3JGg >Ni` >Ni09Hѹ``JLN^NuNV>aN^NuNVBWa .a`2 y<g > N*`.aJ@f >N*`a6N^NuNVBWN_a~J@f> N*p` >N_B@N^NuNV0y"|p00yy yf.aBy.a.a.aN^NuNVH*n yfJmg mg >*N*`< yf2Jmg mg >+N* mn mn >+N*JL N^NuNV y<gB@`.apJ@fB@` 9f#` 9Jf#`n 9f #`R 9f #F`8 9f #` 9f # `B@`( y3 y0(|3Da>pN^NuNVHaJ@fp>/<aXOJ@gf3D.aJ@g >N* yg >"N*09y.aJ@f > N*.a`>/<aPXOJ@g 3F`>/<a2XOJ@gb.aJJ@g >N*09|@3.aJ@f > N*.a< yg >"N*`b>/<aXOJ@gb~<9.aJ@g >N* yg >"N*|m|o >!N*02|A|N`3`>/<aFXOJ@g".a^J@g >N3`>N*JLN^NuNVBWN_ yDf.Jm o >N*09 y` yNXf.aJ@f >N*`f.afJ@f >N* yHf0 yf >"N*09@Hм @0y` yg >"N*09|yN^NuNVHa4J@f.aJ@f >!N* yAf><.aN*`09@Hм @> yf >"N*.??9WaXOJLN^NuNV yDf0.N_l3<#By >N_` abJ@f y<g >N*Jo o >N*.aJ@f >N* yf09|8|f >"N*0y"|f0029 |t aAyy.aN^NuNVHBGNcp|g&].a:aJ@f > N*`><BWN_JGg aJ@f > N*.a:`.azJ@g>aX:<9|8.aZJ@f|g| g >N* yf >"N* yfy@0yy y0T yBPTTy.aJLN^NuNVH*nBENcp>|g>-/9NdXOJ@g:\Ncp<|f >(N* 9ܰe <d(./</9/<Nqh N,fJyjnJ>/<?9Nz|\O|g./<NqhXON+#3j y>SyjTT0JLN^NuNV 9ep`$>,/9aJXOJ@f>N*B@`pN^NuNV 9ep`B@N^NuNVH BJyg:Jyjg37a`.Nqh*|BGyl .aRG`Jyjg37a&.NqhRy(yd0,|f.av`JL0N^NuNVH *|dBI @Jg2(T,fJyf,gl.Nйg(l `P`JL0N^NuNVH*nJyjf-f .al`^(MJyjg-faB-fRy./< NqhXO`-g./<NqhXO`|./<$NqhXO>?-atTO>?-afTO-g.+Nqh`8-g.3Nqh`"-g.;Nqh` .BNqh&MBG|l.?NwTORG`.?-NwTO-g$.BgNwTO.?-NwTO`$.?-NwTO.?-NwTOJL8N^NuNVRyJylf4 y2o37a.INqhRyRylByda./<c*BG<9`:909@Hмz @0ya09y.a>|@f09|8|g >N*`(09|8|g.aTJ@f >N*09|r `y09|8@y.aJLN^NuNV yf09|8|f >N*N^NuNVHNc>|o0`|g]B@JLN^NuNV nJPgB@` n0( n fp`B@N^NuNV nJPgB@` n h m n h np`B@N^NuNVaJ@f yg yf09@Hмf @0y y DfF09|8|f09|8|g >N*09@Hмf @0y`.aJ@g0.aJ@g"09|29|t aAy`409|8| f09|8| f y`>N*N^NuNVaJ@f.a`J@fL 9f409|8|f.N_L`azJ@f>N*` >N* 9f.N_La`, yg >"N*.aN*09|r `yy.a(N^NuNVaJ@f.aJ@f >N*.alJ@g09r `|y`: y<g >N* y<f >N*y.a09y.aN^NuNV`NFn 2AHЁ @0@RG`` 2AHЁ @0@>//9NdXOJ@g\```nJEf >(N*0JL N^NuNVH. g:<`BE~<<@JGg0ngFGF`0JLN^NuNVHaJ@f.a8J@g><<9*|`*.aJ@g><<9*|` >N*0|8|(g >N* yf|@02t aA2|Ay y0T y0TTyJL N^NuNVaJ@fj y<g >N* n l >N*.a@J@f >!N*09r `29 |AyN^NuNVaTJ@fn.aJ@faBJ@fX>N*.aJ@f >N*09r `29AHҼ"A2Ayy.a N^NuNV09@HЮ @0yN^NuNVH*nBUBmB;| ;| BmBmJL N^NuNVH0.@H*@BF.a>#/9aDXOJ@g& yfp`09;@:<\`>(/9a XOJ@gV\a>|f ::;|`D|g]a>JGl&JFf a(|g>N*`]`h0|:>,/9aXOJ@g\a;@ Jm m m o >N*;|>)/9aPXOJ@f(a|;@Jmm mo>"NqhXO yd@RydDo.jNqhBydN^NuNVHJyjgrJygh>9309ʰylRa4>/<lNqhXO.qNqh>a*> abN)v3JygRy`3a>/<NqhXO>?9aFTO>?9a6TO> aJnf.Nqh`X*|BG09@@l>?aTORG`9g >?aTO> a|l.NqhRG`09ʰyn nf > at`&BWa,Jyg> a^N)v3RyJL N^NuNVH y*gJng. y g Jyg>aN)v3``|BE y gJygz y fR|lLRE0|f~`~0Gg > aRF` y fN)v3` y g$Jyg>a|N)v3RF`tJLN^NuNVJyjgNRy09|7m/</<NqhPO./<NqhXO3N^NuNVH y RJ. g <b. 9,>>/<,?9fN~\O#,JLN^NuNV0y"|lJpg:> 0y"|t?00.|Wa\TO09@Hмl @BP`@0.@29AHҼt"A20y"|l0029AHҼl"ARQN^NuNV09HBWN_ 9e.aJ@ga83<#` yg >N*>9|?Gy0y|y.a(J@f >N*.a`a(J@f> N*`>N_.a,J@g09r `| y`T y<f.aJ@f >N*Jm o >%N*09 |r `y0y"|f00yyJLN^NuNV33#3 33 3"N^NuNVBWN_ yDf609@Hмf @0y.aJ@f >N*`j yDf.aJ@f >N*`D yDf" yf y<g >N*`&`.a*J@f >N*09y.aN^NuNVaJ@f yDf..a~J@f >!N* y<g >N*`X.a*J@f >!N* y9g y8f09yg >N* 9TBy09|y.aN^NuNVHaJ@f yg >"N*.aJ@gR.aJ@g,y@09|r `29|Ay`p.alJ@g y`.aTJ@g>.aFJ@g yH`.aJ@g>93N*Bma>W a|fRU`U0`aо|g8JFf >+/9aXOJ@g \U`JFg U(;|`U>W aF`>-/9aXOJ@gX\>(/9aXOJ@g8\a>JGl  `"0| :a,>W a`f]NQ>gx|f >N*|fJyg >N*|g|f. yg$Jyg y gJyg >N*;G >W aX`a>JGm2: yf|m|n >N*>W a`.7N1< 9d]JyNg;yf ByN+y;y>(/9a0XOJ@gRF`$JUf0JygJyg yf :8;|` :9;|>W axJL N^NuNVHa0>|m|n 0|``|g]pJLN^NuNVHa*>JGm |n0``|g]pJLN^NuNVH y f y*h-g \0-`pJL N^NuNV>)/9aXOJ@g\` > N*N^NuNV .eB@` n f n0(n gB@`pN^NuNVH9H*|BF|l az:RF`J9g*9H>/<|NqhXOJ9fB@`'N*`(.N0N+`|g|g|g`N^NuNVH >9G*|(|0SGJ@g >?aFTO`JL0N^NuNV.Nw.Nw.9H??9afXON^NuNV.Nw.|Nw.9H??9a,XO.9H??9PaXO>NxVN^NuNVH>NxV0. "yBW/<|N-4XO=@J o  o<<` . <>/<?.Nz|\O>Fg.|/<NqhXON+>/<?9N~\OGg.?N0N+0H `x>NxVJLN^NuNVH| BGn l*:.B0e|| m|7`|0>aYFRG`JLN^NuNVHNBW/<qNy6XO>/<qNy6XO>/<qNy6XO-|g .2. HЁ @B=|*nJgJg  o mR`JgBG 2HЁ @  oR 2HЁ @ lB 2HЁ @ Am 2HЁ @ Zn 5pH| `5pH" 4H҂"ARG`J5pg 2HЁ @BRG f0>NxVBWBg/ RNy\O|g.R/<gaPXO` N2n!MRn` N2n!|2/-/ N&|gp`*.?<NTO>N>NB@JL N^NuNVHNh>JGlp`>N>N*@Jn fJnf.q/.N XOJ@f 0`@`.v/.N XOJ@f0` >/.?N\OJ@gp`0JL N^NuNVHNh>JGlp`|>N>N*@Jnf.q/.N XOJ@f 0`@`.v/.N XOJ@f0` >/.?N\OJ@gp`0JL N^NuNVH*n :.H>N2(@fp`NgB@`Bgp`6g./ / a6PO` f./ / aPO` -EJo.,gpg2>"/</ 2/,/ N&|gp`>!/</ 2// N&|g .`)G ,-@&L2 мdDJo@<f , o)l .`4`< fRR` SRR`` , o)l .JL8N^NuNVH*n(n ..-G --@ -g -glg2>"/</ 2/-/ N&|gp`>!/</ 2/./ N&|gp`^+n "-¼Ё&@2 мdJo SR`Jf - o+mNh>JGlp`&>N>/.?N\O<>N0JLN^NuNVH? *n.. (n,.:.BJo<.?<NTO+G..?NTO8JDg `RSR` JL0N^NuNVHBG|l>aRG`JLN^NuNVH >aP*@0.@B+|BB B-I мd ` м.dB`JL0N^NuNVH>.0мJLN^NuNVH nep`>N*@fp` JL N^NuNVH|BG|l0yf y0`FRG`pJLN^NuNVH|BGnlFRG`0F@yB@JLN^NuNVH. gRn*y0.H.Nn|fp`*y0.Hѹ JL N^NuNVH *n(n Jg*Jg&H>a*H>a op` lp``B@JL0N^NuNVH. <am <zn< HJLN^NuNVH*nBGJgRG`0JL N^NuNVH*nBGJgRG`0JL N^NuNVH?BC..,. Jf# <`po #B``Jl D.RCJl D,RCfzB` xm`BJgm`|f D# D`# JLN^NuNV/. n/Nؿ"n"N^Nu/ *o// /NPO**_NuNVBBJlDRBJ lD RB0. -@0..?.NTOJL N^NuNV.N>/.?<N~\O. N>/. ?<N~\O>/<v?<N~\O>Nx$N^NuNVHIBBn .RdRn-\ fRn-\*\&Lg(K<%gH>/?.a\O`Bn<-fRn| <0fG=|<0m*<9n$JnlBnH2. A|=@`=|<.fBn<0m <9nH2. A|=@`Bn<lfRnA-HH`@Jng -|u<`-|vlBW/.?<?< // NuTJngT`BW/<vlBg?< // NuT`Jng -|u<`-|vlBW/.Bg?<// NuTJngT`Jng -|u<`-|vl<XgBW`>/.Bg?<// NuTJngT`N-\&L`F=[0.@B.`4H>/?.a"\O``H |xr W h0N.N=@0.nl Jnm=n0.n=@Jnf^ . g. n -f$Sn nH>/?.a\OR0.SnJ@o.H>/?.at\O`0.SnJ@g nH>/?.aJ\OR`0.SnJ@o.H>/?.a \O`` nf nBJL8N^NuNV0.`@. .` RB -@Jo>!/./ /./ N&H,ݮ ѭ   - o+m g .`Jf .`g0>"/</ 2/-/ N&|gp`^>!/</ 2/./ N&|g  .`&߭ - o+m G2JoS` .JL8N^NuNVH *n.. |.?< NTO0| .?<NTO.HH̼IJo JoSS`Jo R "ҼJL0N^NuNVH*n :.H>N2(@fp`JnB@`gp`g>// aPO`g>// aPO`hf./ / abPO`R-EBJoF ,-@B ,g8g2>"/</ 2/,/ N&|gp` ,g8 , l.>!/</ 2/./ N&|gp`)n ,-@&L2, мd"Jo  f < g< `SR` мe2>"/</ 2/./ N&|g .`$`@Jf , o)l .``JL8N^NuNVH*n(n ..-G --@ -g -gg2>"/</ 2/-/ N&|gp` - l0>2. An=@ .gDN^NuNVH *n(MJgR` JL0N^NuNVH*n(n &MJgR`g` JL8N^NuStack Overflow$C runtimeCON:LST:a6xxxxAas68symb.dat N"?AFADA@AB4+<Sdv!+=Jev.end.equ~.yxzorgLNfilnpsu&   label redefinedinvalid labelinvalid opcodeno label for opdopcode redefinedillegalH>Nk`@ n ..H?NvTO`& n  @"n R``J@g|gư|g.HN^NuNVH*n<.H n. nfzJgJEg SE``j nf&z JgJEg SE`JEf-`/ ?. N~\ON^NuNVH*n ;|A+HJnfB@`p=@>?</.Ny\O:JL N^NuNVH*n Jmn*A+H>/-?N~\O|gp`;| m RSm. HJL N^NuNVH*n .0.@?WaTO.?.WazTO0.JL N^NuNVH*n><m;|A+H>/-?N~\OGgp`B@JL N^NuNVHBG|l >NxVRG`BBgNTOJLN^NuNVH>N2*@fp`H|g>N>NB@`g.f(>B?.Nn\O>/<{?.N~\Og,>"/</ !/</ 2/./ N&|gp``>/ 2aXO+n "-¼Ё&@2 мd JoS`Jn$@ .ѭ - o+m .`0>"/</ 2/./ N&|gp`R -@Jo*>"/./ /./ N&H".gp` . . .ѭ - o+m Jf .`g,>"/</ 2/-/ N&|gp`^@ -+@ - l$>!/</ 2/-/ N&`>/ 2aXOG2JoS` .JL8N^NuNVH*n>. 0SGJ@oB`JL N^NuNVH*n.. <.-GJo,  f0| .?NTOHH.?NTOS` .JL N^NuNVn n o0. r `=@ Wn > 0n /?.Nn\ON^NuNVH>N2*@fp`F0.`&+n `0 . ѭ`& - Ю +@`p``J@gְ|gذ|g` -JL N^NuNVH*n >N(@G -:f" am zn H|`H|TBG  o6|l0 .g* am zn H|`H"K4G@RGR` .f:RBG  o0|l* am zn H|`H"K4G@ RGR` nf.?<NTO.?.NTO>|nB@`pJL8N^NuNVH  exprundefined in equateinvalid first operandinvalid second operandundefined symbolillegal index registerillegal constantconstant requiredillegal formatillegal stringillegal addressing modeillegal relative addressillegal text delimiterrelocation errorsymbol requiredbad use of symbolinvalid data listmissing )register requiredillegal sizeillegal 8-bit displacementillegal externalillegal shift countinvalid instruction lengthbackward assignment to *illegal 16-bit displacementillegal 16-bit immediateillegal 8-bit immediateSymbol table overflow & Usage: as68 [-p] [-u] [-L] [-N] [-S d:] [-F d:] sourcefile .opd.data.text.set.dc.globl.comm.bss.ds.evenaddaddiaddqsubsubisubqcmpaddacmpasubaandandiororicmpieoreorimovemoveqexgjsrbsr.evenoverflow of external table 68000 assembler initialized end statement not at end of source i.t. overflow #$%()*@$#$$:$h##$nAinvalid radix in oconstsymbol tab r8Ѐr9ЀY r10Ѐg r11ЀK r12Ѐ r13Ѐo r14Ѐr15Ѐd0Ѐd1ЀYd2Ѐd3Ѐ}d4Ѐd5Ѐd6Ѐd7ЀCa0Ѐa1ЀG a2Ѐy a3Ѐk a4Ѐ a5Ѐ a6Ѐ a7Ѐ wuspЀ KspЀccrЀ srЀ.bЀ.BЀ .wЀ .WЀ.lЀ.LЀpcЀ PCЀ abcdaddQaddaaddi addqPinc_Paddx %andandi maslasrbcc 7dbcsuebeq)gbgelbgtnbhibbhis dble obloeblsle overflow doitwr: it buffer botch I/O write error on it file && %d: %s & %d: %s as68 abort & %d errors Unable to open input file Unable to open temporary file & Unable to read init file: %s can't creat init: %s & Write error on init file: %s & %d: %s!&*+-/<>333343N3h334!&()*+-/<>^6B6B6J6X6F6B6B6F6F6F6B6|expr tree overflow expr opstk overflow seek error on it file write error on it file G LfO$RfShETDTVRfWfX"YVYZZYWf[x]^T^VV@@0 @@KKKKK`@ @  @ @& Unable to open file %s I/O error on loader output file it sync error itty=%x doitrd: buffer botch pitix=%x itbuf=%x end=%x it read error itoffset=%d -EXTERN1E3iW{#y5kCW_g=a'g'K9o]OOW_g  /+SUw [ [  w   i i  s  YY I /k ; c  ] - 5?%Gq  +  K # = =K cks{77mmII[[ cbloscblt mbmi kbnefbpl ]jbvc Whbvs Sibchg@bclr Ebra`bset {bsr abtstchk Aclr Bcmp cmpa cmpi cmpm dbccTdbcs Udbeq !Wdbra 3QdbfQdbge\dbgt^dbhi Rdble _dbls Sdblt ]dbmi [dbne wVdbpl sZdbt PdbvcXdbvs Ydivs edivu eor eori / exg ext AHjmp Njsr oNlea AlinkNPlsr +lsl Omove amovea@movemHmovepmoveqpmulsmulunbcdHnegAL SYMBOLS- S y m b o l T a b l e %-8s *UNDEFINED* %-8s %-8s DATA TEXT BSS ABS && UNDEFINED SYMBOLS && %-8s %4d %4d C P / M 6 8 0 0 0 A s s e m b l e r %s Page%4d Revision 01.01Source File: %s & outword: bad rlflg & Read Error On Intermediate File: %s & Object file write error Cannot open Cannot create CDOSUXcdosuxsrrsrs8srrsrs8s.opd .end.data '.text.equy.set.dc.globlM .comm .bss .ds .even# ~.yxzorgR0ЀR1ЀR2Ѐ!R3Ѐ1R4ЀER5ЀR6ЀiR7ЀR8ЀR9Ѐ R10Ѐk R11Ѐ R12Ѐ R13Ѐ R14ЀR15ЀD0ЀD1ЀD2ЀAD3ЀD4ЀeD5ЀD6ЀD7ЀUA0Ѐ A1Ѐ A2Ѐ A3Ѐ A4Ѐ A5Ѐ A6ЀA7Ѐ+USPЀySPЀsCCRЀSRЀr0Ѐr1Ѐ sr2Ѐr3Ѐr4Ѐr5Ѐ r6Ѐr7Ѐ }Dnegxk@nop NqnotForori peaH@resetNprolror roxl roxr rteGNsrtr Nwrts KNusbcdsccTscs 9Useq WsfQsge\sgt ^shi Rsle_sls Sslt]smi[sne5VsplZstPsvcXsvsYstopNrsubsubasubisubqQdecQsubxswap H@tasJtrapN@trapvNvtstJunlkNXP(f, yP>/<?N#XO>a  "yPѩ JLN^NuNVH yP(g.RaN*@a` yP(gvJng.Ra$*@PgRyT.Sa *@Pfa`8JngRyU#U`$ yP0(mf yP ( g.a$` yP Lg JyRga\JL N^NuNV.j /./<@N#PORy=8N^NuNVH >N:#H9HgRH 9Hм#H#HP3,P*|R(|SBG| l *B(BRG`JL0N^NuNVHa@HЮ#V yV*h f*yP` yV P!yP.a JL N^NuNVH*n(M&yPBG|lLg*m`RG` JL8N^NuNV yV P yVJf yV!yPaN^NuNVP 9PHe<>N:f.@7N#>N,`HydPN^NuNVHBG*yPBF|l H@RF`0|>JL N^NuNVH *n(n BG|l8RG`JL0N^NuNVH y<H"y?</<aJLN^NuNV 9XFѹT 9XJѹXt 9XNѹFTN^NuNVH #PT(|R*|TBG|@l*RG`(|S*|UBG|@l*RG`JL0N^NuNVH #`7'`4C Runtime Copyright 1982 by Digital Research V01.03 o"h&IB[b#D>E?/ N!N,NVB odpN^NuNV0/"/ NBD>d0< A<"NB0<NBN^NuNVHa4aX#LZ#HdH#ZXf nn.?_N#>a*n X~nlJ(].?}/ N:XOJ@g, -fRH`S`J,g./<?N#XO>N,#R/ afXO#Xb#XbT`Ryj>R/ a>XO#DD`Ryi>R/ a XO#V`pRy=4`fRyJ`^&yPRBF|l JgRRF` yP1|BWa`.# PN.a >RG`aJL8N^NuNVB9<.F\N,NN^NuNVTP*|R(|TBG|@l*RG`*|S(|UBG|@l*RG`JL0N^NuNVH 9T̐Xb#i#XtL#FTVJyjg #DDXt` 9TR#Xt#XtDDJyig #VFT`$ 9XtйLR#FT#FTV#XbTa a\JXjgD.P/<=aXO.Ra*@+yi mm.a*@PfJFXgL.P/<= aXO.RaR*@ 9iйL+@ mm.az*@PfJXngR.P/<=*aLXO.Ra*@ 9iйLйV+@ mm.a *@PfJL N^NuNVH*yHPd6-f&-g 9Xtѭ `-g 9FTѭ `JL N^NuNVH(|RĹSd0G @Jg &SJ g.a"`.a*Kg&k`P`JL8N^NuNVH *n.P/ aBXO.Sa(@Pg n!l ``B.RaҾ l.- B .a *@Pf;| 9FTйV+@ n!m ߹V.SaaJL0N^NuNVH *n.P/ aXO.SaP(@Pf.Ra:(@Pf.@uN#>a.ab*@PgJ g .a`:`.a J@f,JyVf.@N#RyVRy=8.a`+l JL0N^NuNVHa`.a`J@gڰ|g|g.aNJLN^NuNVH*n.6Bg?<N XO.Bg?<N XO|m>ajB- .Bg PRINT "LEW"  yHBP#?aJ@gaByTByU#Vj a>a09TưyUo8JyUg .UaaXZ yHRP yXf ?XXf`aj9? g.F\N+nR?09jHй?ѹ?.F\/9?a:XO`BTHN^NuNVH *|VBG|l.F\N+nRG`BV#V?J9VfB@`pJL0N^NuNVH*n -f.R @ lf"R @Jg<`6<*|<`*n>/<F\/ N+0PO3F\l./<?N#XO>a #j .XD?9F\alTOJ@g.j /<?N#XO>a TByF^ yeXDgBWB?9F\N7*\OaVJyHg>/<J/ N+0POJL N^NuNV>/U?.N.t\O|gp` n 0B@N^NuNVH*|XDBG|l.F\N+:RG` y`XDg.j /<?N#XO>a JyX^g.j /<?N#XO>a hJL N^NuNVH yZ P 9XFйXJм,Jng 9?м܀.F\/a XO.9XRJoaaz>a`JLN^NuNVH*yPBG|l.F\N+:RG`.F\N+:.F\N+:.F\N+;@JL N^NuNVHB yP(f~ yP(g.9T`Z yP(g.9Xt`D yP(g.9FT`. y*nBG|lJgH>N)&``RG`> N)&JL N^NuNV.a ymXDf3ja<`: yeXDf3ja$`" yF\N,N>JN,NN^NuNV>/9a@3H#HH09jyig.H?<`N*TO`.H?<`N*TO.H?9iN*TO.H?9iN*TO.H?9LN*TO.H?9LN*TO.H?9VN*TO.H?9VN*TO 9PH-@.H?.N*TO.H?.N*TO.H?9RN*TO.H?9RN*TO.H?9XbN*TO.H?9XdN*TOJyJg.HBgN*TO`.H?N,N^NuNVH yH>THJGgJ0SGJ@gB yXf*XXf.F\/a4XO.J/a(XOaap#?>ata`JL#Xnp`B@JL N^NuNVH *n(n BG|l gB@`RG`pJL0N^NuNVH 0.*@J.AN#(M PdJgH>N)&R`> N)&JL0N^NuNVHN9LBW/</</<f0>N,NBWBg/ RN-\O|g.R/<AaPXO` N2n!MRn` N2n!|.?.NTOJL N^NuNV.N;r>/.?<N2z\O. N;r>/. ?<N2z\O>/<A?<N2z\O>N,N^NuNVHIBBn .RdRn-\ fRn-\*\&Lg(K<%gH>/?.a\O`Bn<-fRn| <0fG=|<0m*<9n$JnlBnH2. A|=@`=|<.fBn<0m <9nH2. A|=@`Bn<lfRnA-HH`@Jng -|'f`-|(BW/.?<?< // N(/ N8|gp`*.?<NTO>N9n>N:\B@JL N^NuNVHN:$>JGlp`>N9n>N9*@Jn fJnf./.?N7\OJ@gp`0JL N^NuNVHN:$>JGlp`|>N9n>N9*@Jnf./.?N7\OJ@gp`0JL N^NuNVH*n :.H>N9(@fp`NgB@`Bgp`6g./ / a6PO` f./ / aPO` -EJo.,gpg2>"/</ 2/,/ N8|gp`>!/</ 2// N8|g .`)G ,-@&L2 мdDJo@<f , o)l .`4`< fRR` SRR`` , o)l .JL8N^NuNVH*n(n ..-G --@ -g -glg2>"/</ 2/-/ N8|gp`>!/</ 2/./ N8|gp`^+n "-¼Ё&@2 мdJo SR`Jf - o+m .N^NuNVH..Bp Bp BW/ n 0?N7*\OJl.j /<@N#XOa n Bh . P"n #@l. N+nR`JLN^NuNVH 0.*@J-f - `2.P/ a@XO.Sa(@Pf .Ra(@ , JL0N^NuNVH 0.*@J-f(M`..P/ aXO.Sa(@Pf .Ra~(@>, gp`` gp`` gp`B@JL0N^NuNVH B*|H(|DL=| yZ#JXZ 9XFйXJйXRм(Jng 9?м؀.J/a8XO(9XFUJmBn.F\N+>.JN+<TBn0|`t.?N*TOJyJg .?N*TO`d=GJyJg .?N*TO.F\N+=@.JN+<TRnU0|`0JyJg .?N*TO`.` 9TѮJyJg .?N*TO` 9XtѮJyJg .?N*TO` 9FTѮJyJg .?N*TO`Rn0@>axѮJyJg.0@?aTO?N*TO`0@>aFЮT̐T-@ .m o&.j //<@N#PO0@>aRy=8BnJyJg .BgN*TO``|b@0@? PNJy=4fnJnfh .g\JngV.j /<@N#XOJng 0@>aTJngT`BW/<(Bg?< // N(T`Jng -|'f`-|(BW/.Bg?<// N(TJngT`Jng -|'f`-|(<XgBW`>/.Bg?<// N(TJngT`N-\&L`F=[0.@B.`4H>/?.a"\O``H |Ar W h0N.N;P=@0.nl Jnm=n0.n=@Jnf^ . g. n -f$Sn nH>/?.a\OR0.SnJ@o.H>/?.at\O`0.SnJ@g nH>/?.aJ\OR`0.SnJ@o.H>/?.a \O`` nf nBJL8N^NuNV0.`@.H>N)&`@ n ..H?N)TO`& n  @"n R``J@g|gư|g.HN^NuNVH*n<.H n. nfzJgJEg SE``j nf&z JgJEg SE`JEf-`!/./ /./ N8H,ݮ ѭ   - o+m g .`Jf .`g0>"/</ 2/-/ N8|gp`^>!/</ 2/./ N8|g  .`&߭ - o+m G2JoS` .JL8N^NuNVH *n.. |.?< NTO0| .?<NTO.HH̼IJo JoSS`Jo R "ҼJL0N^NuNVH*n :.H>N9(@fp`JnB@`gp`g>// aPO`g>// aPO`hf./ / abPO`R-EBJoF ,-@B ,g8g2>"/</ 2/,/ N8|gp` ,g8 , l.>!/</ 2/./ N8|gp`)n ,-@&L2, мd"Jo  f < g< `SR` мe2>"/</ 2/./ N8|g .`$`@Jf , o)l .``JL8N^NuNVH*n(n ..-G --@ -g -gg2>"/</ 2/-/ N8|gp` - l0>!/<FRy=8Jng" yXf-h>/<AN#XOBBnJng.?.N*TO.?.N*TO`<0G-H`.j /<A#N#XO>a`|b@0@?, PN`@Hf*|P(|X|(9XJ`"JL0N^NuNV 9iйXbTg.AJN#Ry=8.L9TH?/<Pa\Oa0JyJg6.i9j H?/<DLa\O.L9XrH?/<X|af\O.HN*BW/<?9HN7*\OJm>/<H?9HN2z\O|g.AfN#Ry=8>=8aN^NuNVH*n.N*>N,N0. "y<>/ /<a&Jo .N+>.H?N*TOU`JL N^NuNVHBHJyX`f8*yHPd*-f-f Lg JyRg.a`JL N^NuNVH *n(MH(MBG|l.H?N*TORG`.H?-N*TO# ?L.H?9?LN*TO.H?9?NN*TOJL0N^NuNVH*n n f~` n f~` n f~`B``BH|0m |9n|0`&|am |fn|`|Am |Fn|``JFmn l 22HЁ*``` JL N^NuNVH*n./<=aPXOJ@g #Xjp`6./<= a6XOJ@g #FXp`./<=*aXOJ@g N;XOH. 9DH` JL N^NuNV>/ ?. N2z\ON^NuNV yB2n*>/ ?<N2z\O|gp``. H`XJyB4n4#B:B6>/9B6?9B2N2z\O|gp`$3B4 yB6 RB6SyB4. HN^NuNVH><yB43B4#B:B6>/9B6?9B2N2z\OGgp`B@JLN^NuNVH*n ;|A+HJnfB@`p=@>?</.N-\O:JL N^NuNVH*n Jmn*A+H>/-?N2z\O|gp`;| m RSm. HJL N^NuNVH*n .0.@?WaTO.?.WazTO0.JL N^NuNVH*n><m;|A+H>/-?N2z\OGgp`B@JL N^NuNVH*n BmJnfB@`p=@>Bg/.N-.\O:JL N^NuNVH*nJmnA+H>/-?N.t\O;@Jmnp`Sm mH|RJL N^NuNVH*n.a>|fp`0<|F.a>|fp`0|@g <@0JL N^NuNVHBG|l >N,NRG`BBgNTOJLN^NuNVH>N9*@fp`H|g>N9n>N:\B@`g.f(>B?.N7*\O>/<"/</ 2/-/ 2/./ N8|gp``>/ 2aXO+n "-¼Ё&@2 мd JoS`Jn$@ .ѭ - o+m .`0>"/</ 2/./ N8|gp`R -@Jo*>"/./ /./ N8H".gp` . . .ѭ - o+m Jf .`g,>"/</ 2/-/ N8|gp`^@ -+@ - l$>!/</ 2/-/ N8`>/ 2aXOG2JoS` .JL8N^NuNVH*n>. 0SGJ@oB`JL N^NuNVH*n.. <.-GJo,  f0| .?NTOHH.?NTOS` .JL N^NuNVH>N9*@fp`F0.`&+n `0 . ѭ`& - Ю +@`p``J@gְ|gذ|g` -JL N^NuNVH*n >N9(@G -:f" am zn H|`H|TBG  o6|l0 .g* am zn H|`H"K4G@RGR` .f:RBG  o0|l* am zn H|`H"K4G@ RGR` nf.?<NTO.?.NTO>|nB@`pJL8N^NuNVHN:$>JGlp`&>N9n>/.?N7\O<>N:\0JLN^NuNVlx in %s : short address overflow in %s library offset = %x : lo68: invalid relocation flag in %s : finalwr: text size error : output file write error : unable to reopen %s : external name: Cannot open Cannot create CDOSUXcdosux%$%%$%b%$%%$%b%B:H? *n.. (n,.:.BJo<.?<NTO+G..?NTO8JDg `RSR` JL0N^NuNVHBG|l>aRG`JLN^NuNVH >aP*@0.@B+|BB B-I мd ` м.dB`JL0N^NuNVH>.0м^JLN^NuNVH nep`>N9*@fp` JL N^NuNVH|BG|l0yD0.H.Nn|fp`*yD>0.HѹD> JL N^NuNVH *n(n Jg*Jg&H>a*H>a op` lp``B@JL0N^NuNVH. <am <zn< HJLN^NuNVH*nBGJgRG`0JL N^NuNVH*nBGJgRG`0JL N^NuNVH?BC..,. Jf#DH <`po #DHB``Jl D.RCJl D,RCfzB` xm`BJgm`|f D#DH D`#DH JLN^NuNVH *n(MJgR` JL0N^NuNVH*n(n &MJgR`g` JL8N^NuStack Overflow$C runtimeCON:LST:lib6.a?P?V?W`##O yC <a" y$0<"<NB g 0<"<NB0<"<NB @fA (ШШ мм h`fJhfAC2E#J"(#A#ABiB90<;" NBJ@f|$i %h.i/ /9/*A8C8 <aDNu(+)+,(,)+0P+\,::p4T72V# ,+\2Z#:,+p6^# 2`7(,-(,)4f7:&h , ,C,a,n,n,o,t, ,l,o,a,d,_etext_edata_endLLLLLLLLLLLLLLLLLvLLLLLLLLLL$LLLL:LL@LLlLLvL^zvv<<<<<c.outloxxxxA: Invalid lo68 argument list .o: Illegal option %s .o: unable to open %s : read error on file: %s : file format error: %s : no relocation bits: %s : Invalid symbol flags: %o : %s duplicate definition in %s : symbol table overflow : Unable to open temporary file: %s : asgnext botch : Undefined: : Unable to create %s : seek error on file %s : relative address overflow at %DDT1 68KSkQNu0< 2<fNB/9Nu Cannot load DDT1.68K. $a,d,`` .м-@.NJ@f N`| .2.HR-@ .bRN|J@fR.N`> N> N=| -n .мd .м` .-@ .bp0.`4 nH>N`4 n0>Nv`$ n .N```|gư|gҰ|g> N0.@R@n0.HѮ` n<@RnDl > N`-n .мd .м` .-@ .b nH>NR`> N` .R"n "N^NuNV.PN.3 //PNPOJ@g6.NJ@g(. /././././. /a`NN^NuNV.?<N2XTOf.3N`-n n -P-n Bn.?<;N2XTO=@0.`-n n0 n"n!i n"n!i  n"n!i n"n!i n"n!i n"n!i n!n n!n n"n -nY n YY n"n n!n n!nJ nBh n"n  n"n  nB(\ nB(8Bn n l& n2n| ] n2n| 9Rn` nB(| nB(X nB(h nB(D`\.3(N`X`L.3PN`H`<.3\N`8`,.3qN`> N0`4 nH>N`4 n0>Nv`$ n .N```|gư|gҰ|g> N|S.?< N2XTO> N N.H=AHB(Jnot ..fB@`rA-HR . @Jg2 n am n zn nH|` nH"n`A-H.Q/N$XOJ@g` NB@`R . @  f` nJf0|f .nJm|f .nJl NB@`0` ."n nHH".g .N`d ."n2 n0H".g .N`8 n n ".g .N``|g||g|g0HѮ`JLN^NuNVH.PN.Y/PN$XOJ@f-|.NJ@f N`Jnf . N .SJg\Jng . N n , F>|NBg|NCfT F> F0J. N0 F0` . N1vN|J@gB` n"n JLN^NuNV.NJ@g . NN^NuNV.PN.3//PNPOJ@f N`X.NJ@g2 n Pg N`6 n -h n (ЮS-@`d.PNFJ@gL./PN$XOJ@g4.PNFJ@g&./PN$XOJ@g.NJ@f N`.?<`(``J@g||g|g|g`.NN^NuNVH.PN>.Y/PN$XOJ@g` NB@`|g.g NB@`t.PNFJ@g.Q/PN$XOJ@g` NB@`D.PNFJ@g./PN$XOJ@g` NB@`.NJ@f N` .b0|f .nJm|f .nJl NB@`0HЮ".Rb0`z ."n nHH".|g .N`^ ."n2 n0H".|g .N`4 n n g .N``|g|g|g0HѮ`RJLN^NuNV.PN n -P./PN$XOJ@g-nBn.PNFJ@gP n m N``:./PN$XOJ@g N2n!nRn` N``.NJ@f NB@`Bn0.nl4 N2n2n"6"A1Q0n 6 @0JRn` n . N0Bn0.nl"0n 6 @"N4n0Rn`. NN^NuNV.PN.Y/PN$XOJ@gf.PNFJ@gX.Q/PN$XOJ@gD.NJ@g6 .Ю.N`> N ..N`> N`NN^NuNVH n PgN`j n &h*nRIBJgN2XTO.?<N2XTOf.3N`nB. .ذnL.?<N2XTO.?<N2XTOg.3N .R-@`.?<N2XTON^NuNV.3N.N.4NN^NuNVH. HH.?<N2XTO< f0| .?<N2XTOJLN^NuNVH*nBGJg H>aRG`0JL N^NuNVHBBF n*PRH>a4J@gH>a\H"Ё.RF`S n n 0JL N^NuNVH. <0m<9o<Am<FoB@`pJLN^NuNVH. <0m<9n H|` `H|JLN^NuNVH. < l H|0`H|7JLN^NuNVH..<. :.|m0YF 2>a<0gBEJEgJFf H>af`JLN^NuNVBW?< /.a\ON^NuNVBW?<0n/a\ON^NuNVBW?<. HH/ah\ON^NuNVH. B.< m<~op.`H@.Ua JLN^NuNV.4aN^NuNV.4a.aT> aN^NuNVR nJg n  gB@` `R`pN^NuNVH *n(UR  g ,gB@`2  fR`JfB@` ,gS*p`R  fR`S*pJL0N^NuNVH*nR U  fR`SJL N^NuNVH *n(UR @ Wf~`2t tNV.HBG|l00|H"N4G#@^0|H"N4G#@~RG`BP-|T-| X=|\BBBn..P///./P/.a.a-@f` nH`./.aXO`.P///./P/./.a`X.a`L.P/.N XO`4.N `&../.N XO`./.N @XO`.N j`./././.N@ `.Nr`>//P/.N `BW//P/.N `j../.NXO`T../.NXO`>.P/.NXO`(.2N``|D|b@0@2t PN`:JLN^NuNV.2N n ( ]g*././././. /./.\aRN^NuNVH *n.3NR.?< N2XTO> N-HJFg M2FB(IJg am zn H|`HR`IBG  o m FlRGR`FfB@` JL0N^NuNVN^NuNV.PN=@.]/PN$XOJ@f$.NJ@g n -P` NB@` ng .gR.PNFJ@g$./PN$XOJ@f NR`G.3/ \/PNPOJ@g(.PNFJ@g.3/ 8/PNPOJL8N^NuNVH.PN.Y/PN$XOJ@f$.NJ@g n -P` NB@`.g NB@`.PNFJ@g&.Q/PN$XOJ@gBG` NB@``-n~.NJ@g .c NB@`dBF .c JGgT| lNN|J@fD.N`> N#>N > N09>HѮRF n `JLN^NuNV.PN.Y/PN$XOJ@g` NB@`.PNFJ@g.Q/PN$XOJ@g` NB@`t.PNFJ@g./PN$XOJ@g` NB@`@.NJ@g .c NB@` .b n"nRR`N^NuNV.PN.3//PNPOJ@g.NJ@g.?<N2XTOf.3N`B. n -P-n -nBnJnfH .мn8.?<N2XTO.?<N2XTO=@`Jnf .3N n0 n!n .Ам"n#@.N n `NN^NuNVH.PN>.Y/PN$XOJ@g` NB@`\|g.g NB@`B.NJ@f NB@`(.N` Lf~`~S*.a0JL0N^NuNVH *n n B( n B( (UR<am<zo<Am<Zo<0m<9oB@`" ,:fH|"n T` n BBF<am<zo<Am<Zo <0m$<9n|mB@`0F GRFR`|l0F | RF`BF|l, nJg0F "nQ R` 0F | RF` .gS*p`bBFR<am<zo<Am<Zo <0m"<9n|mB@`.0F G RFR`|l0F | RF`S*pJL0N^NuNV.?< N2XTOg.?<N2XTOp``B@N^NuNVH *n0`.47a(`BG|lI0@HBF|l0`&.4[a`*.4aa`.4ga``J@gְ|gܰ|g0`.4la`.4ta` ` J@g|g.4|a.aP.4aRF`v> a6RG`R.4ah.a.4aV.a`D.4aB.a.4a0 -ЭS.a``J@g|g|g> aJL0N^NuNV.a J@g . ap`>R . @ Df. /.?<Da\O` n Af. ./.?<Aal\O`S./<4aXOJ@g. /<4aXO`./<4aXOJ@g4. X/<4axXOJ@g n ( f n "n !iJ|G>a> N<9>f|Bp f9>gg >>fWa >,N>a `>>fWa V>,N>a FJLN^NuNVHBE>9>f|<9>f|F|f|g|f REF|f|>aT`|> N>?9>fW?aTO>,N>9>f|Bp gJEg>a `>aZJLN^NuNVJnf.=N` nf.=N` ngaN^NuNV.=NN^NuNVH>.|o >QWa ``>a 4JLN^NuNVH<.|8F>.|0`>a ` >a `>a Z`>a `>a h`a>a 8`>a`B0` y>h=PT>hTy> y>h=PT>hTy>>$N.a 4`~ y>h0H(gT>hTy>.a `PaX.=N`@>az`6> a `,`|b@0@: PN`|b@0@: PNJLN^NuNVH y>h>T>hTy>>$N>a JLN^NuNVH y>h>T>hTy>>$NH>Wa z>(N nf.=N`>a>,N0r `>Wa g .=N>)NJLN^NuNVB nf y>h=PT>hTy> y>h=PT>hTy>.=N.aN^NuNV3>6N^NuNV(N>a>)NN^NuNV>(N>a>)NN^NuNV>-N>aN^NuNV>a>+NN^NuNV>?< /.N \ON^NuNV>?<0n/N \ON^NuNV>?<. HH/N \ON^NuH?2H20<2<32P$<1NC#2L o#2R3 2VL/92Ry2V?92VNw32V#2R|_H2 .y2,o,2R=y2V n H?0<292P$92LNC-y2 F-y2J,y2L?2NuH?2H20<2<$<1NC#2LJ\O0<2<$92LNC0<2< 32P$<1NC#2L y2 h#2R0( @32V"hJNaL/92R?92VNs0/#2p"/NB"92pNu(622Nf2222tUnknown Command DDT-68K Copyright 1982, Digital Research -68KCannot open program file Insufficient memory or bad file header Read error Bad relocation bits Unknown program load error Cannot open file File too big -- read truncated. Cannot create file`x./<4a^XOJ@g2. P/<4a0XOJ@g n ( g n "n !iJ`0./<4aXOJ@g.  /<4aXO`a n ( g n "n !iJ` n "n !iJN^NuNVH*n.4aZ.a> a .4aB.a> a.4a(.a> a.4a>- >a.4ag .4a g .5a.5a0|@>W0a|g .5 ag .5ag .5ag .5a~g .5 an> a$.?<Da0TO..?<AaTO#>N > aJL N^NuNVH*n R @ 0m< 7n6.a J@g,n UB.H@HЮ.@/YaXO`aJL N^NuNV>/. /.aPON^NuNV>/. /.aPON^NuNVH *n(n >.BE.av>=a,0`H>a`$>a`.a``|gܰ|g|g> a|S.?< N2XTO> a.HJFo0FB(A-HR . @Jg2 n am n zn nH|` nH"n`A-H./aXOJ@gJ.aJ@g>0`$ .`( .8`(``|gְ|gް|gz`.a\J@fa 0JL0N^NuNVH. H>H9>gHJGg :G>h` y>h0H*@>hT>hTy>.=N.a&JL N^NuNV> N9>fg09>f|r `>a`>a>,N>?9>fW?aTON^NuNVH9>fg >lN` >rN<9>f|F|gb>a$> N>9>f|Bp g9>gg>aJ`JGf~>#N>a|>,N>>fWa`> N>?9>fW?a(TOJLN^NuNV> N>?9>fW?aTON^NuNVH09>f|@>a`>9>f|Bp g> N>>fWa>,N>apJLN^NuNVH> N>>fWaN>,N y>h0H*@>hT>hTy>.a0JL N^NuNVH>9>f|Bp g<9>f|:9>f||HfPGPF`|fPF> N>a>,N>aJLN^NuNV> N>>fWaN^NuNV> N>aN^NuNV> N>?9>fW?a~TO>,N09>f|r `>PWa0N^NuNV.=NN^NuNVH09>f|@>a>9>f|Bp gJGf~.=NH>a>,N>?9>fW?aTOJLN^NuNV.=N>>fWaN^NuNV> N>>fWa.>N. File write error. Unimplemented Function: ? Bad or non-existent RAM at ERROR, no program or file loaded. text data bss base length = base page address = initial stack pointer = Start = End = PCPCUSPUSPSSPSSPSTSTPC=USP=SSP=ST==>TR SUP IM= EXT NEG ZER OFL CRY;6;;;@H@ ;E ;JT ;NU ;SW ;XQ ;]\ ;b^ ;gR ;l_ ;qS ;v] ;{[ ;V ;Z ;P ;X ;Y ;T;U;W;Q;\;^;R;_;S;];[;V;Z;P;X;Y;;@;р;;;P;;;<<`< d< e<g<l<n<b aBG|l*> a n .aVX |f> aRG`> aJLN^NuNVH *n(n aJL0N^NuNVH *n(n Jg RHf`Jf.aJ@gp``B@JL0N^NuNVH 9>T#>h3> y>3>f*|5&0y>fmg `.NJmm mnJmg0-`a`a`ap`a`a`a.`a`a`aJ`a`a$`ax`a`a *`|a B`ta T`la `da `\a `Ta `La ^`Fa z`@a `:a Z`4a `.a `(a `"a L`a n``|b@0@:N PN> N` >?NJL N^NuNV.=NN^NuNVH>9>f|Bp g09>f||f.>aN|09>f||f|.=NPG`<9>f|F>aj> N|n 9>ff$>?9>fW?aTO>,N>a~`">av>,N>?9>fW?aTOJLN^NuNVH<9>f|0|fBG`|0f~`| f~`a>a> N>?9>fW?a(TO>,N09>f|r `29>f|AA<>?aTOJLN^NuNVH>9>f|G>aT> N>a>,N>?9>fW?aTOJLN^NuNVH>9>f y>h0>a~T>hTy>N^NuNV9>gg .>N> N9>fg(>?9>fW?a.TO>,N.;aF`@09>f|8| f .:a,`.;a">,N>?9>fW?aTON^NuNVH y>h<T>hTy>*nzBG|lB0]g(JEf >/N|g>a^>-Nz`|f >SWaBBERG`|f .> NJL N^NuNVH9>gg .> N> N>9>f||f09>f|r `>a>,N y>h<>a>>fWal|f>,N09>f|r `>aT>hTy>JLN^NuNV.>N>>fWa>,N09>f|r `>a8N^NuNV09>f|@>a> N09>f|r `>a>,N>?9>fW?aTON^NuNV09>f|@>axaN^NuNV> N>?9>fW?aTON^NuNVH>9>f|JGf.>N` > N>?9>fW?aTO|f.>N`|f .>NJLN^NuNV09>f||f .>"Na\N^NuNVH>9>f|9>gg.>%N>aL`.>-N>a:.>1NJLN^NuNV>DN>N>NN^NuNV>AN>N>NN^NuNV>8s_mytpr>`s_mytc>di_snrt>fs_odt>he_ysbmfu>lt_odt>pf_ysbmlo>te_rrlfg>~d_tonic>s_ysfmgl>d_to>s_ysbmlo>t_ysm>s_ysvmla>s_myubf>s_myeln>s_fefagl>s_feafrd>t_xestmy>dxaddxaddaddiaddqandandiasasbrabccbcsbeqbgebgtbhibleblsbltbmibnebplbvcbvsbsrcmpimovepmovepmovepmovepbchgbchgbclrbclrbsetbsetbtstbtstchkclrcmpmcmpmcmpmcmpacmpaeorcmpdivsdivueoriextjmpjsrlealinklslsmovemovemovemovemovemovemmoveqnbcdnegnegxnopnotororipearesetroroxroroxrtertrrtssbcdstopsubxsubxsubxsubsubisubqtastraptrapvtstunlk*unknown instruction*illegal instruction format # .l.b.l **illegal size field (PC)PC,.l#$ $unknown opcode #$ #$,#$.lA7.l #$ SR,,CCR,SR.l.l USP,.l ,USPr_aecdmom_iani_inthd_silpyaZe_mcdf_limlmel_aopdmgc_elnaRg_codm h_xeamht i_cnmolt d_sisam @m_vomeme jr_aefdl@s_teemmrt_arec v_mcdw_trifeld_muymh_xehcrag_teofmrp_tuhcras_ottug_teehx$i_hsxeth_xeavlp_tuehx p_tuehlx`p_tuehwxvp_tuehbxp_tuybetb_dab_daarmn_moroeg_teespFd_bealknp_raesk_yeiht|s_ohvwlae_aximens_ohswatp_adergc_pm Rp_erlg:p_erwgRp_erlgorp_ergjt_yrlfga 4o_tpba5&n_ion"i_fn1""i_fn2#i_fn3"i_fn4#i_fn5$\i_fn6'i_fn7(8i_fn8(i_fn9)Ti_fn01)zi_fn11)i_fn21*.i_fn31*i_fn41*i_fn51*i_fn61+i_fn71+,i_fn81+i_fn91+i_fn02,i_fn12-$i_fn22-i_fn32.i_fn42.fi_fn52.i_fn62.i_fn72/i_fn82/Bp_nitsr p_srzie$p_trpo%np_trerg%Bb_daisez%.p_irmm'|p_rapid0"p_rd/p_ra/p_rai0p_rapii0:p_drsip&p_irdnxe&h_xezls0Rh_xezws0nh_xezbs0i_instvs'r_gesm0k:r_gesm1k;p_tulrsi,p_rdi/G_O0S_ETP1vB_ODS2Xs_vsla>6l_ubfRD`0|.?<NPTO:REJ9Lgp `|`B@`t0мLB29PЁ @ (:fn0yP2ҼL0H:0|TyP0мLB29PЁ @Jf(Ix| bRD`J9Lgp ``B@``0|.?<NPTO:RE(MRx|b$0мLB29PЁ.aF:RD`0мLB29PЁ.aJ@fRyP`0yP2ҼL0HHr.f2RyPx|b$0мLB29PЁ.a:RD`BCx| b B2Ё @ ?fRCRD`0JL0N^NuNVH?>.BCBnB.0CLJ(g0CL (:gRC`0CL (:f|gBW/<favXOB@`8J9̀g.,?< NPTOB@` 9:gf( 9Afm 9PfoBW/<fa$XOB@`.p?<a TO9pH|@=@.p?<NPTO<|f.?< NPTO8LRDBE|gVJGg0Dʹ( fJGf80Dʹ( f(J.gaDB.JEfB0..?<NPTO`"=|.p?<NPTO<8LRD`NRF0|:.?<NPTO0| .?<NPTOv| b>| f0| .?<NPTO |ʹ0`H|H.?<NPTORFRC`0| .?<NPTO.p?<NPTO<|gHRE8LRD|f6BEJGg0Dʹ( fJGf0Dʹ(`Nt+PNPNPCOPYRIGHT (C) 1982, Digital Research B9P ON3tNx0<29tANB0< 9tNBONq`0/"/NBNu"<0<?NB#z#~#pvp;"<vNBJ@f29Rp NBB"9|"ApNB |BQ/<p?<NW`\Bp\av/<p?<NW`\Bp8a\ y"y/)@@_?! !<QN`Ns @f"<`" @f"<` @f"<`"<p NBpNBй @"|pBp#QNuNV0| .?<NPTO0| .?<NPTON^NuNVH *n(n JgHop`Hlp`RR`JfB@`pJL0N^NuNVH *n(|8Jg \g`BJL0N^NuNVH0|.?< NPTO<0|.?<NPTO>|Aa,JFgB| e|1| 0|0@|$`0|0@|$.Y?< NPTOB0.?<NPTO0|>.?<NPTOJLN^NuNVH *n>. |fa<(MJg \gR`JGf ?BJg \gHH.?<NPTO`JGf LS`aNJL0N^NuNVH*nBG fa.`|`Jng.aJGg.D?< NPTO`.H?< NPTOJLN^NuNVHJ9ff".^?< NPTO>/<fa"XOJ9̀g.,?< NPTOB@`@BG0GLJ(g0GL (:gRG`0GL (:f.|f 9Afm 9PfoBW/<faXOB@`.p?<ajTO>JGfJ9fg.p?<NPTO|bp.p?<NPTOJ@fXBG|bN0H@B@H@мʹ @ g |ʹ0pHH.?<NPTO`.p?<NPTOB@`:RG```2J9fg*JGc.?< NPTO`.?< NPTOJLN^NuNVHBDJ9ff^.p?< NPTO>/<͚aXOJ9͚fB@`.?< NPTO>/<faVXO=̀`pBG0GL (=g0GLJ(gRG`0GL (=f0GLJ(fx 9=ffx0GL (=f0GLJ(g J9̀gx0GLJ(f 9=̀f J9́gx0GLJ(f 9=̀fJ9́f J9͚fx0GLJ(f 9=̀gx0GLJ(f J9̀fx0GLJ(fJ9̀g 9=̀g J9͚gxJDfJ0GL (=f:0GLB(RGBF |L0pH2FL@NRGRFJ@g`=̀JDf J9fgJ9͚g.?<aTO>.p?<|d80 @"|./ aDXOJ@f0 @"|00`~RG` 9:Mf4J9Nf,J9ff$9LH|m9LH||np`:.pBgaTOJ@cp`$ 9Syf 9Uzf 9B{fp`pJL N^NuNVH *n(|Jg  g \gR`  fR`BGJg \gRG`B \f.Jg*N  fR`J9Fg#V`#Z`ZJ9FgLJ9Jf#nV.8aN`$B9FB9DB9B yZJgN`B9NJL0N^NuNVH *n.. Sހʹ.ʹ?< NPTOJ9͵gaX9͵H|Hмʹ @| (|Ͷ  fR`  g2d. am zn H|`H  f  fR``BJL0N^NuNVH*n \gJgR` \g  fR` JL N^NuNVH *n(|LBG|hdBRG`BGJgb \g\|dVBF \g,  g&Jg"|d0B2ЁмL @RFR`B02ЁмL @BRG  fR`JL0N^NuNVH*n  o .g :fp``B@JL N^NuNVH*n *fp?`.aJ@f RyPH`p JL N^NuNVH? >.*n Bv |#b B2Ё @BRC`v| b B2Ё @ RC`J9Lg<?`< ByP(M0мLB29PЁ @Jf>Rx| baxTO<JGfJFfJ.m . oxJDf..?<NPTO|g.?< NPTO`lBE~|#b"0H@B@H@мp @"N4ERERG`J9pm 9poxJDf(.p?<NPTOJ@c.?< NPTO`.?< NPTOJDg.?< NPTOJLN^NuNVHJ9ff".^?< NPTO>/<fa|XOJ9ffB@`J9̀g.,?< NPTOB@`.p?<aTO>JGcBJ9Ff:.?< NPTO>/<̀aXO 9Ǹg 9ỲgB@`2 9Ǹg(.p?<NPTOJ@c.?< NPTOJLN^NuNVHJ9ff".?< NPTO>/<faXOJ9̀g.,?< NPTOp`| 90fm 99foB@`b9fH|о| cB@`LJ9gg0 >9gH@|о|dJ9hfB0.?< NPTO`B@`3RpJLN^NuNV9LH|3TB09T.?<NPTON^NuNVH0|.?< NPTO3RBFB9L.pBgaXTO> 9 yf 9 zf 9 {f6y8zK{.p?<NPTO|b|`0|.?< NPTO.p?<NPTO|b|`v y z {B09R.?< NPTO.p?<NPTO|b|`,0|H@мn @BRG``D0H@B@H@м @ g.0H@B@H@м @JgJGc0H@B@H@мn @\RG=DJFgBEJGcr0H@B@H@м @ g0H@B@H@м @Jf0H@B@H@мn @B`SG0H@B@H@мn @B0H@B@H@м @ fJ`B9n0H@B@H@м @Jg(0H@B@H@м @2HABAHAҼ"ARDRE`0H@B@H@м @B0<`` RD`0H@B@H@мn @BJ`0R@|e |d0H@B@H@мn @BRG``0R@=@JFgnBERD0H@B@H@м @Jg(0H@B@H@м @2HABAHAҼ"ARDRE`0H@B@H@м @B0H@B@H@мn @BRG0<`0H@B@H@мn @2HABAHAҼ"ARDRG``H |br W h$N`J9JgB90<``zJEc"0H@B@H@мn @ \g ndSE`JEfB9B9`Z0H@B@H@мn @BBE nd,0H@B@H@м @2.HABAHAҼ"ARnRE`0H@B@H@м @BJL0N^NuNVH*nBG|d0H@B@H@мn @BRG`J9BfJ9DgBG|d0H@B@H@м @BRG`BF~J9g>?/ a\O<|f.ʹ?<NPTOBG|d`0H@B@H@мn @ am(0H@B@H@мn @ zn |n0pH|` |n0pH2HABAHAҼn"ARG`B@`.?<J9g"J-gS--H|5`H>a` >/ aRXO`о<fJ9gB@`p`<f>/ aXOJ-f`<f >a`<f>#a>aB-`f<f8>#a>aBF-H|@d>5`H?a>TORF``(>H"M-H|H@?aTOR-`xJL0N^NuNVH.sp?<"?<NsXOB9$B9B> NV>Ns*@ -#b#j -йb#^#f.NfJL N^NuNV09RF@yPByRByTJngB@NF#bj#^f.Nf>NsN^NuNV0.`:.Nv`B.Nv`4.Nv`&.,Nv``J@g°|gʰ|gҰ|g.>Nv9H>WANt>a N^NuNVH*n>UG| g|!fp`F|m |%n|`JGm| op`&0G+h$0G!m$B@JL N^NuNVH*n-g.#j#f-g#jb#f^`+yj+yfJL N^NuNVH>.yJGg,|0S@@p.H`yRg >Ny` |B.-n-n -y.N<JFgBWNy0JLN^NuNVBW/90n/abPON^Nu.?< NPTO.p?<NPTO|b|`H.p?<NPTO|b|`,0|.?< NPTO.p?<NPTO|b|JFg4JGf0.^a>0|.?<NPTO3T@NQB09R.?< NPTOLB@JLN^NuNVH>.BE0|.?< NPTO8|f8J9ff0.^?< NPTO>/<faXOJ9ff0`:.?a. <.=|BDJ9HgBD|d00H@B@H@м @ g0H@B@H@м @  gRD`ʸ|d*B9H0H@B@H@м @  fTD`J`*.κ?<NPTOJ@gB9HJB9n`bJ9Jf |d|d |0@H`и|d00H@B@H@м @ g0H@B@H@м @  gRD`ʸ|f&0H@B@H@м @  g=|H`,0H@B@H@м @  fTD=D`JB9H`TJGc,ng&0H@B@H@NPTO.κ?<NPTOJ@gJB9HB9nBGJ9Jf >?/ a2\O.ʹ?<NPTOBG|d`0H@B@H@мn @ am(0H@B@H@мn @ zn |n0pH|` |n0pH2HABAHAҼn"ARG`JL N^NuNVH*n.a`BWa`>a`aX`a`a`aJ@f.?< NPTO`a`|` aJ@fBF>aJ@g$J9Ff B`DF`\|gVBG |L0pHRGJg`SG0| bBW/<LaXO`BW/9^aXO``| b@0@ PNJL N^NuNVHL.ʹ?<NPTOJ9@g2B09T.?<NPTOB09R.?< NPTOB9@J9Ng*J9Fg*yV`*yZB9N>/ aXO`*ah*|P J9P f>/<P aXO`B9P Jg#^.aJ9Lg .LaJ9Ff .a*@`J9Bg4.a*|n.^ah#Z.8aB9BB9D`.J9Dg.aߔ*|n.8aB9D`.a*@Jf6J9Jg*yZB9FB9BB9D``*|n.8a`Jg >/ aXO`JL N^Nu @>g,H @2g/??NVHPOLNs A0LNC`W Ns$/` 4/`"/`2/0/HNCLxNu/H/Nu/ o /NVH>.>/90G/a>PO< yh d0H"y")Ё/a _0JLN^NuNVH*yB| ޝSFJFf rހ ހ JL N^NuNVH?*n >.(y8<g 09R@`B@<g0,` y0(@b0|f:M>al dtB0"y")Ё&@gaF`Ra>gJ y1lvB9Hk0yTgyR`0F@yP9H>N~`~3?0|HH@B@H@й// nN J@ggBD`0|`RF`0JL8N^NuNVH>.0<2|`? y (2IHABAHAЁ @_JLN^NuNVH>.JGg.0<2|`F@? y (2IHABAHAЁ @_JLN^NuNVH y<( y*hBGFb*0H5HF2<4|aAg >a40`RG`pJL N^NuNVH*n H||lV y1nBG y hd5pH>WN}RG|o`0G>Ns>N}RG|oJL N^NuNVH. 09PHhF@<9fJgtB.H@H||o >NyHr@@.N#f >Ny y#  y#JgP y<(>N}0SFJ@f y*h y: >B/<~|N|pPOpH`мn @2HABAHAҼ"ARDRG0H@B@H@м @  f |dRD``RD|d0H@B@H@м @ 0m0H@B@H@м @ 9n |0@H6|(M Sf& Uf Bf Mf If Tf  fRC(MzCb  gJgR`  fRRE`  g&Jg" \g|d0H@B@H@мn @RG`RD`0H@B@H@м @Jfb.?<NPTO.κ?<NPTOJ@g4J0H@B@H@мn @$RG0H@B@H@мn @B`BD`0H@B@H@мn @$RG0H@B@H@м @ $fRD`RD|d0H@B@H@м @ ^f*0H@B@H@мn @2HABAHAҼ"ARDRG`0H@B@H@м @  m@0H@B@H@м @ ?n* |0@H|2HABAHAҼn"ARDRG`L0H@B@H@м @ @m@0H@B@H@м @ _n* |0@H|2HABAHAҼn"ARDRG`0H@B@H@м @ `m@0H@B@H@м @ n* |0@H|2HABAHAҼn"ARDRG`0H@B@H@м @Jfd.?<NPTO.κ?<NPTOJ@g4J0H@B@H@мn @^RG0H@B@H@мn @B`BD`J`&0H@B@H@мn @2HABAHAҼ"ARDRG`JFg0`D`RD`0H@B@H@м @  g0H@B@H@м @  f |dRD`ʸ|e|d0H@B@ 0H@0 _NuNVJ9gp` >NsN^NuNVHB>NsJ@gX>Ns<f >Ny<f<`,<fB`"<fJ9gB@`p`JfJLN^NuNVH. axH>?<NsTOJ9gH>?<NsTO< mRy`< fBy` <fSyJLN^NuNVH. < f> az09|f`"J. g< l >^aX<@H>aJJLN^NuNVH9B9JgH` >NsJLN^NuNVHaH>a<fJ9gB@`pHJLN^NuNVH>.|fa|`"` |fa``>W?<NsTOJLN^NuNVH*nH9gBWH?aTO`JL N^NuNVH>.> aF> a>JGg > a2SG`JLN^NuNVH*nJ-gS--H|`BF>. 0SFJ@g& M2F(< fPG|` < lTG`RG`Ҿyd>a> a>a`JL N^NuNVH *n=yJg\ yH<|RH|Fd<FIJFg"> yH?aTORSF`B`B--H|H|Alta<f"J-f>?<a^TO>Ny`B< g< f> a`.`&<f>/ aXO`<f:yPJL N^NuNVH *n(n >.0SGJ@g`JL0N^NuNVH *n(n ~  ?HH@|gJgB@`LSGJGfJ.g> ?g HH@"y)HFAgB@`TTHH@|?gB@`pJL0N^NuNVH*n>/. / abPOg0- > / /. a POG -p9H`yTHJL N^NuNVH*n(n >/ / aPOJ@g GA-H y hd:~ nJgJg nHf` n` nRRSGJGf`6~ nJPgJSg n0Sf` n6` n0TTSGJGf.N<, H|EbEf"-H|,H|Ao mF m - g >Ny0.@>N{p`p9H`yRB@``B@JL8N^NuNV|.NJ@gBWNy n(gB@`BW/./<N|pPON^NuNVpN^NuNV>/. /.azPON^NuNVH*n>. ?f$9H>a(>/ /<N|pPO<`..NB -? gB- B->/ /<N|pPO<>/9/9aPO0JL N^NuNVH*n(n >. gB@`pgPG|BSFJFf> / / aPO0@>N{ yhc y1Gp9H`yTHJL8N^NuNVH *n(n >.BW/ / aJPOgj, g T>Ns`F>?<NsTO`(.Nv`.Nv`Ns`0< "` ByPByRByTB9`H>N~`.]aB- B-BW/ /<N|pPO:`.]a.N<:`#.]Bg/ N\O:`j*y-M.]?</ N\O:`H.]aV>/ /<N|pPO:`&.]a4BW?</ N\O:`.]aBWBg/ N\O:`.]aB- B- B-B->/ /<6N|pPO:`.]a>/ /<TN|pPO:`09P`9H|`#`tp9H`yR`^09R``.]ab>/ /<N|pPO:`2>/ /9NPO`0||b9H|`.]a>?</ N\O:`.]a>Bg/ N\O:`.]a.N`.]a.NP`0F@<yPyRBE`r.]a>Bg/ N\O:`T>NV`J#BWNy.N`:.Nzr`0.Nz`p`"`|?b@0@V PNJ.g0JL N^NuNVH *n(mHJg H>SW` 9H>N~|JL0N^NuNVH*nBGH`-H>9H??< NsXO+@`-H9gBW-#BNu @lH {NNsl(nJB9B9Bav3NP9g <NuBNu9g9Nu?a29gNu99g9g <Nu9<g9g9gNu9<g9g9g9Nu< ap< ahNuga^`Nup<d^A gH @"(C9<eB@`K9<J5faNuBA3NuNuJg BH0H`0Nu#Nu9aDJ@f B"AaRNua,J@f A"Ba:9<faNuBJ9g:9<<j*3ahB9Nu <Nu9NuBNuI A  Nu9gNuA9g9g`Nu9gNuaxaa99<A|f  g9g |aNutxav9<ahaWNutxaX9<aJaDaWgaNu<a09<a"a09<Nu<Ja 9<aa.aNu&@a>Ny0@>N{ y hd|SF4`H>WN}JFf`|SF0F>Ns>N}JFfHJL0N^NuNVH*n(n >.BW/ / aPOgD, g >NyGA-H| H|"nRSFJFf0@>N{HJL8N^NuNVH *n(n >.BW/ / a8POg> / R/ RaPO0@>N{HJL0N^NuNVH*n- H|H-H|?Ht 塀JL N^NuNVH*n.a- H|HЁ-@n!n"n#JL N^NuNVH *n(n BW/ / axPOg*.ah,H|HЁ-@n!n"n#HJL0N^NuNVH*nBBGB>/ /<N|pPO|d&m!m"m# .o-n~`n!n"n#JL N^NuNVH. H>aB y*hBFBD yhb,JFf <<0F@:0Fg y(HR@HހNRD` y JL N^NuNVH *n(y,H- H,HArF`>0- H|4aAJL0N^NuNVH*n>. Jng0G>Ns` ` 5pH|JL N^NuNVH*n>. <.-Jng M2G/?NsTO _1@` M2GFJL N^NuNVH>. *yB0.-HH-H. HBHЁ,>/9/N{>POJH??< NsXO(m&l.Y?/-Ns\O>0+W?< NsTO.?.?<NsXO>?< NsTO. ?< NsTO f> Ns>`-H>?<NsTO>`*>Ns>`J@g |g0|g(|g0JL8N^NuH o<d y`gQG33$y$9B69m&a`Ha&<m" aapJAfV`Jg"9adaPJAf63&aH$y$9Syf$y$9gBfa<aza~&49|f9A9<pApAp( Jg|ּؼ"D&'C Nu~$9<<9gC1pg9@&ּ"CA9 NuAAvaQaaNu#<9abaRz a89||@g,<<g |a`<g |aQpNupNu9BBBBB9<<9B9CJ1pg:|N3C1p<9fyf9gLa3a3t9SBԼ"9Nua6 |a,9|Aaa |aaP< <rfaNut"QNu Program Load Error$ insufficient memory or bad file header$ read error on program load$ bad relocation information bits$ NON-SYSTEM FILE(S) EXIST$Enter Filename: $Enter Old Name: $Enter New Name: $File already exists$No file$No wildcard filenames$Bad file name$Confirm(L N^NuNVH*nJng,-!H@-"HAA-"<-#g<`-<?- R< mBR<@mp`H-H|?Af*H- H@"y)HFA|fF B@`\.N<|ep`JGF BW/ /<N|pPO|e(J. gp` >/ /<6N|pPO|ep`B@JL N^NuNVH *n~I J$fSGJGf y hcOBp"y)HAo0"y)HF- HB|AJL0N^NuNVH*n.a>- H@f-H|``- H@c0<``B@JL N^NuNVH? *n. y6(|Jf- g >NyJng0>H?/ a\O=@g0.`T-#H|@ `& - fBWH?/ a\OJ@gp`"B- m.a- H|AbJgp`-- HR@@.aZ:>?/ a\O<JFgJgB@`p8`Jgp`N~$<|fp`>??/ aPOx nfV(y#:<SE0Hй @BJEfBE y(H@n>H??aXOxRE`#>- H??apXO=@JnfnJnfR- 0.JL0N^NuNVH>.<. *n B.-MBE0`BWNyNu~`BWH?NtTO`>Ns`H>?<NsTO`jH>?<NsTO`T>Nu`SfNupNu>GONp``"` ````` pNuJZNuJZNuf<E4NuJb,܅$Nu"9a.9<HG69GlCRF&yK` aJAfrQ*9$E(93BL`SCjaXJAf>&y6<?a4SJf$y(9SyfNu!y .9޹!G"y"""""""".(,)ܙ,|zBbc.JQ"$hfpNBR@BNupr$<HNCLRAX Afr A"g A#g A0mpNC @JX"$Ԑ&9b(9^p o# bcb cBJQNuaaaaaaa~azavaranajafaba^aZaVaRaNaJaFaBa>a:a6a2a.a*a&a"aaaaaa aaBgH瀀 /  @$o @Xm( @tn @0 y Jf` @(m@0@ @lLJ_T@ @oP@?AVa0aAea aAxaBNBNs/P Nh @m(/ fN!/1/N`L/o\ONs/ f2!/1/!/!/N`L/oNs?o`?oLNsBgpNB`Nu?H@a0?Ha0?Ha0@ @ m02pNBNu |aB9Y/N)? $Enter User No: $.SUB file not found$User # range is [0-15]$Too many arguments$nP P  $;\^kmkm"gh&g@m@impppppqqq(qpDIRDIRSTYPERENERAUSERSUBMIT Permanent disk$ Disk select$ Disk change$ Read-Only file$ error on drive $z(0Tj&Bt6Vt Exception $ at user address $. Aborted.L CP/M-68K version 1.1K Bios version 0 Not ready Write protected on drive Type R to retry, A to abort ,`  ,``p,`,`? 4 4@< 0.nmH> ?.SWaTOHй/\/.NHPO>SWa>0. W?.aTO`>at-@>ah2. HЁ-@>a=@>SWaBn=@>/./.NHPO> /./.NHPO=n0.no">SWa>0. W?.a TOSn`>0. W?.aTOJn f NVJ@f3Z y0("yRiRya.NqN^NuNV y> y0?aTO y> y?(aTON^NuNV ng n f`>Nm4-@> Nm4-@ n0(n f n0ng .Nqr.a?/.aXO_|l` n=h n=hJnn .Nqr .\-@Jnf .\-@Bn`0>SW/.aXOHЮ\-@>SW/.a|XO=@>SW/.ahXO=@>/./.NHPOBn0.nl0>/.a4XO>0.W?.0.W/.aT\ORn`.Ng.Ng n hg( n>Nm4-@ n"n0.Ng 9f# n0(yP n"n0(i n"n1i0. yLf3L.a.NqN^NuNV n1y2 n32 nBh.NgN^NuNV y2g$=y2>Nm4-@ n32`Ry=y>NmNVBn0.yl80.@Hм\ @-P n hf.a n1|Rn`N^NuNVJnm 0.yo .NqrBn0.ylB0.@Hм\ @-P n hg n0(nf.at .`XRn`>aP-@>?9XNLTO=@ nfa.?9XNLTO=@ nfa .N^NuNVBn0.yl(0.@Hм\ @-P n hf`Rn`0.yfa(-@ n1| n1n.a .N^NuNV yXf a*3XBn0.@Hм\ @-P n0(29SAAf`Rn` n hf.a .`0 n hf .Nqr n1| n1| .N^NuNV=n0.n njBn0.yl<0.@Hм\ @-P n0(nf.a n1|`Rn`0.yf .NqrRn`N^NuNV.NL:3( y(faByN=y ng>ah-@ n=h n=h .\-@BnBn0.nlJnf>/.NYXO=@`*>SW/.NYXO??./.NY\O_=@Jng" n2n0H=@Rn>aVSn`> aJ> aDRn`t`4>a2a>(NLj>a#p3P3JN^NuNV09NHм4 @ RyN y<1@@+ @W@,F`z     %&'()*+, -. /0  12!"34#$!"#$1234%&'(5678 )*+,9:;<  -./0 12345678 !"#$%&'(9:;<=>?@)*+,-./0,Fz5-@ n"y1i n"y0 y1n n hg$ n>Nm4-@ n0.Ng nBh.Ng .N^NuNVa8-@.Ng.Ng09JyP=@ y=h09JyPno0.` 09JyP=@0.nlB@`0.n=@NPJ@fP>a,=@ 92.HЁ\-@ .\-@>SWan=@>/./.NHPOBn0.nl*>0.Wa^>0.W?./.a\ORn` n1n y1n y0(yLf n3L .N^NuNV.NL|.NL:3X yXf . a>XNLj>/<8NLRXO3X09XN^NuNV n=hBn0.yl80.@Hм\ @-P n0(nl n0("nRiRn` nBhN^NuNV.NO| yfNUx>/<NXON^NuNV.EaN^NuNV.]aN^NuNV n1|N^NuNV09R@n l> SW?9RWaTO09n o09`0. 3> ?9XNLTO=@ nfaj>/.?9XNM\O|gaJN^NuNV-|409S@"n209R@"n3@09JyP"n3@Jnl .nNqrRy3JP>SW/<4aXON^NuNV n hNf(>/<4?9(NM\O|gaByNN^NuNVJyNf`">/<4?9(NM\O|ga`N^NuNV>BgNCTOaa^.aN^NuNV./.NFXONIa.NN^NuNV y=hN[=@ gJyJm09R@yJl.NO|.aJnm nlJnl.NO|.a\Bn0.nl<>NY=@Jnm0<nnl.NO|.aRn`N^NuNV n=h .\-@BnBn0.nl,>/.NYXO=@0.n=@>?.?.?.RW/</<NwzJnl` n2m.+/<NwzXOBn0.nl nPl0n"n4n0H|=@ n f.-/<NwzXO`> n l>W@/<//<NwzPO`>/<3/<NwzPORn`l.6/<NwzXO=nRn`N^NuNVBn0.yl0.@Hм\ @-P>/<8/<NwzPO n> n?( n0?/./<C/<Nwz.N[> n?( n?( n?(/<q/<NwzRn`TN^NuNV>?9J?9P/</<Nwz >?92?9L?9/</<NwzN[> y?(=P y=h y=h-yJnf> yBh.Ng ng>Nm4#p3J3P` ng\>Nm4#3JP y0.Ng>Nm4-@ n1n.Ng.a`t ng`>Nm4# y0(yP y0(yP3J y1n.Ng3L.aT` .Nqr0.yN^NuNV09JyP=@ y=h>0.WaT-@>aH-@>0.WSWa0??.SWa$TO_=@>/./.NHPO>aj??.0.WaZTO_=@0.n=@=n0.nl&>0.Wa>0.W?.aTORn`0."yi0.yN^NuNV y1n.Ng y=h ng>Nm4#3JP0. yN^NuNVNPJ@g n B@`t>J09PWa-@>J09PWaj=@0. S@no0.`0. S@=@>/./.NHPO .2.HЁ @ 0.N^NuNV n o .Nqraj2. TAAl@a$-@aT2. TAAl* y0(yP#a.2. TAAlaa2. TAAl .Nqr.Ng09JyP=@ y=hJnf(> /9\/.NHPO> BgaTO`f .vNqr n>/.aXON^NuNVNUx y1|BW/.NLRXO3( y(f .a*3aX3J3Pp3L3By-|:3H3B@=@33p3P3JJynZJnfT.NO|>?9J09PW/<4NZ\ORyJ>abB@=@33`nJynf09T@ny>a(>0.W/. .2.HЁ/NHPO09n3Bn0<y3at=@ nf^09ng2>?9J09PW/<4NZ\ORyJ=y`Ty yg >av`v`n n f8>?9J09PW/<4NZ\OUyRyJ=y`. n f`x` 0.29HҮ"ARySy`R>(NLjJyfNUx`v-|4 n1|>SW/<4a4XOSyBy3LNPF09JS@33J3P>aL#ByN^NuNV yHfF09S@ynaTB@33H` RyByH09@Hм\ @#* y*2yH0H|RyHN^NuNVBn0.yl^0.@Hм\ @#*.*?9(NLTO=@ nfa nl0.@Hй* @`Rn`N^Nu y?( y0?/9/</<Nwz y> y?( y?(/</<Nwz N^Nu0/2/NBNu0/"/NBNuNVHNBW/<NXO>/<NXO>/<NXO-| .2. HЁ @B=|*nJgJgHHм @gR`JgBG 2HЁ @JgN5pHHм @f85pHHм @g 5pH| `5pH" 4H҂"ARG`J5pg 2HЁ @BRG f0>NBWBg/ RN\O|g.R/<AaPXO` N2n!MRn` N2n!|.?.NTOJL N^NuNV.NF>/.?<N\O. NF>/. ?<N\O>/<P?<N\O>N~N^NuNV./. /.NwPON^NuNVH*nBn n HR J@g޾<%g.H?NTORn`B. n <-@R Df n R R.| <0fG n R =|<*f-M n=PT n R `8<0m2<9n,JnlBnH2. A|=@ n R `=|<.fBn n R <*f-M n=PT n R `.<0m(<9n"H2. A|=@ n R `B.>/-?N\O;@ Jm n m fm0`m p`Sm +m mH|RJL N^NuNVH. *n BF:-fp`$-fTJfN>N+@+@fm`2m>NJ@gm@`;| H"mR`-gA+H +@ mR-gz>/-?N\O<Bm `n-g>< g -мb" -:>/-?N\O<+mBm `( -:>/-?N\O<;| +mFg mp`H|JL N^NuNVH>ND*@fp`H|g>N>NB@`g8f2 - l>B?.N\O>/<?.N\Og>>"/</ 2/-/ N|g334p`F.?<NTO|f334p`>N>NB@JL N^NuNVBW?. /.a4\ON^NuNVBW?. /.a\ON^NuNV>?. /.a\ON^NuNVHN6>JGlp`>N0*@Jnf./.NXOJ@f 0`Z`./.NXOJ@f0`:>/.?N\OJ@g>N3#34p`0JL N^NuNVBBgNTON^NuNVH>ND*@fp`d0.`6+n NTO.HH̼l0| .?<NTOGJo JoSS`Jo R "ҼJL8N^NuNVHN6>JGlp`&>N>/.?N\O<>N0JLN^NuNVH*n :.H>ND(@fp`JnB@`g3 34p`g>// aPO`g>// anPO`f./ / aPO`v-EBJoj ,-@B ,gJgD>"/</ 2/,/ N|g334p`  ,gJ , l@>!/</ 2/./ N|g334p`)n ,-@&L2, мd"Jo  f < g< `SR` мe2>"/</ 2/./ N|g .`$`@Jf , o)l .``JL8N^NuNVH*n(n ..-G --@ -gT -ggD>"/</ 2/-/ N|g334p`" - lB>!/</ 2/./ N|g334p``>/ 2aXO+n "-¼Ё&@2 мd JoS`Jn$@ .ѭ - o+m .`f><lg<LfR. n R A-HH`R.J.g <|` <|#.?<?< // N{ J.gp`pH`RR.J.g <|` <|#.Bg?< // N{ J.gp`pH`R.J.g <|` <|#.Bg?<// N{ J.gp`pH`R.J.g <|` <|#.Bg?<// N{ J.gp`pH`\-M n-PX`L-M n0|@B.T`2.H?NTORn``H |Rr W h0N.NF=@0.nl Jnm=n0.n=@J.fZ .0f, n -f"Sn. nH?NTORRn0.SnJ@o..H?NTO`Rn0.SnJ@o. nH?NTOR`Rn0.SnJ@o..H?NTO`Rn`0.JL N^NuNVH /<?.?./ /. nN*@fB(n g%H| lp0`p7@`B JL0N^NuNVH*n<.H n. nfzJgJEg SE``j nf&z JgJEg SE`JEf-`N^H+@ - Ю +@`p`*`J@gư|gȰ|g`Jl+| -JL N^NuNV>B?.ab\ON^NuNVH>ND*@fp`<H|gB`,.?<#NTOJ@g334p`gJ.o -.S.ggD>"/</ 2/-/ N|g334p`>!/</ 2// N|g334p`T+G -+@I2Gd gR` " Ҽ2ѭ`B` -.+@+m  -JL8N^NuNVBW?. /.a4\ON^NuNVBW?. /.a\ON^NuNV>?. /.a\ON^NuNVHN6>JGlp`>N0*@Jn fJnf./.NXOJ@f 0`Z`./.NXOJ@f0`:>/.?N\OJ@g>N334p`0JL N^NuNVH*n :.H>ND(@fp`vgB@`jg3 34p`Lg./ / NPO`4f./ / a.PO`-EJo.,ggD>"/</ 2/,/ N|g334p`>!/</ 2// N|g ."/</ 2/./ N|g334p`&R -@Jo<>"/./ /./ NH".g334p` . . .ѭ - o+m Jf .`g>>"/</ 2/-/ N|g334p`^@ -+@ - l$>!/</ 2/-/ N`>/ 2aXOG2JoS` .JL8N^NuNVH*n>. 0SGJ@oB`JL N^NuNVH*n.. <.-GJo,  f0| .?NTOHH.?NTOS` .JL N^NuNVH*n 0.(@G -:f*HHм @g H|`H|TBG  o>|l8 .g2HHм @g H|`H"K4G@RGR` .fBRBG  o8|l2HHм @g H|`H"K4G@ RGR` + fp`2 nf.?<NTO.?.NTO>|nB@`pJL8N^NuNVH *n>. zN6<JFlp`f>N0(@>/ ?N\OJ@fBE.?<NTO>NJEfB@``334pJL0N^NuNVH>ND*@fB@` fB@`pJL N^NuNVHBG|l>aRG`JLN^NuNVHJl D. n  @-"n R`μJg./NjXO. 9,` JL N^NuNVBW/. /.a4PON^NuNVBW/. /.aPON^NuNV>/. /.aPON^NuNVH*n(n BG0&@0+|g |lRG`޾|mB` wg Wf.H>?</ N\O<`~ ag AfH.H>?</ N\O<JFl.H>?</ N\O<`>B?N\O`( rg Rf.H>Bg/ N\O<`B`BJFlB`:Bk 6B@H'@'@ rg Rf7|`7|J.fk JL8N^NuNVN~>NN^NuNVHBG|l0м.N~RG`JLN^NuNVH*n0-|g*.NF-g .NB@H+@+@Bm m>NJL N^NuNVH*n0-| |f. -<JFo >/-?N\O>Gg mp`2-gJg-g;| `;| `Bm +mB@JL N^NuNVH*nSm m mH|R` `.NHJL N^NuNVH. *n Sm mH"m|R``.H?N>TOJL N^NuNVH*n-fp`-g m p`Jf&-f>N+@fm`m-g0Hм+@f9g .NF-g>``)G ,-@&L2 мdDJo@<f , o)l .`4`< fRR` SRR`` , o)l .JL8N^NuNVH*n(n ..-G --@ -g -ggD>"/</ 2/-/ N|g334p`>!/</ 2/./ N|g334p`p+n "-¼Ё&@2 мdJo SR`Jf - o+m .`RB -@Jo>!/./ /./ NH,ݮ ѭ   - o+m g .`Jf .`gB>"/</ 2/-/ N|g334p`^>!/</ 2/./ N|g  .`&߭ - o+m G2JoS` .JL8N^NuNVH*n(n ..gA-H n(g.?<NTOp`< n(g&L.?<NTO n(Hf >N~ n(g Am Zn H| `H n(g*  f$ n(gHH.?<NTO n(gHH.?<NTOp`|l ` <*E.?<  0.*@0.@B+|BB B-I мd ` м.dB`JL0N^NuNVH>.|e3 34p`,0*@f3 34p` JL N^NuNVH? *n.. (n,.:.BJof.?<NTO+G.x.?NTOJ@g |o894Bp d`BD 2HЁ`0Hހ0H0Hր0@H` JL0N^NuNVH|BG|l f 0`RG`334pJLN^NuNVH>.p2`F@HB@JLN^NuNVH*nBGBFHHм @gR` +fR` -fRRF 0m 9n0 >H@|`JFg0D@>0JL N^NuNVH>.ZGB0>RGJf <##By(y*Tmb80X@me(` 2Ё&@0-G7@&(;G# \`f>a*@ fB`(M*T`JL8N^NuNVH >.|?GG0>Nj*@fB` R*@(M9G.\a 9JL0N^NuNVH *n](yceeebf#`J(T` 2-Ёf T0(m T*`* 2,Ёf 0-l(`(#JL0N^NuNV .]-@ n0(=@> aV-@fB`.a@ .ga pattern;findr Backward find.g Enter edit mode at line help Print this messageinject Add a line to the bufferlist 1 9999 List lines to the printerload Replace the buffer with move Move lines of after line name Set filenamenowrap Disable line wrapping.resave Save the buffer to an existing filesave Save the buffer to a new filesearch 1 9999 Search for patterntabs 8 Set tabs to every columnswrap Enable line wrappingusage: inject line-- injecting ---- listing --No file argument.File not found.-- loading --usage: move -- moving --File not named.File not found.-- resaving --File not named.File exists.-- saving --Search mask? Change mask? -- searching ---- searching --next, exit? yes, no, all, exit? File not found.line truncated.Can not open temporary file.Error reading line.@@TEMP@@.TMP@@TEMP@@.TMP@@TEMP@@.TMPBuffer not saved. Proceed ` r``F` ` ` ` ` .xM.a ! 8!l!B!!z!v.xMSa l<>aa (HAa a JAgdvYYa*Ifa0$M&xa0! g&x,K 8c.!"N$Ma "H$M&La`~LISLOANERUSAVNEXLEIGOTGOSURETURREFOINPUPRINPOKSTOBYCALPEERNABSIZTSTE><<@jvZ, l F ^T " . ` p .$ 8> CETa&HBf K`$<.g<g T KBJj`tJjG6RNa!a`Xa x!vJvgDB"Hae8!v ITaCE^`zaDa|"arf`aaha`eaabg <faVgaP`x a:aT`a aH`za# a8`a`av,a`a `?a8"a`a`a>a/"af,/8v/8zB!z`(a"8zg.A!z!v _a`aah!CAE`aL!CDE`na8`p!!v!,O` gf$O"NGav.K`Jae>"@ 8g4ga^` иih""8JjAm!v x`a.`` aJfN"HBad:`l.x~~0. nd=n .d&-nJng n"nRRSn``< .B2.Ё-@0.H@B@H@ѮJngSS n"nSn` .N^NuNVH. gRn*y00.H.Nn|fp`*y00.Hѹ0 JL N^NuNVH*n(n &MJgR`g` JL8N^NuNVH *n(n HfJfB@`RR`HHAJL0N^NuNVH*n(n &Mg` JL8N^NuNVH *n(MJgR` JL0N^NuNVH..,. Jf#, <`Hc #,B`:fzB`(xe 〼b`BJge`#, JLN^Nu o BNu o0/H.X,X.NuNVH *n(n Jg*Jg&H>a*H>a op` lp``B@JL0N^NuNVH. <am <zn< HJLN^NuStack Overflow$C runtimeCON:LST: +-bdeghkmpqsuxzjt~  ,   N  :? Bad argument.Bad argument.Bad argument.New line too long.Too many ?'s in change mask.New line too long.line truncatedline: column: ..no file.. wrError: Warning: @@DATA@@.TMPbuf_gobk 1buf_gobk 2buf_gobk 3buf_gofw 1buf_gofw 2Not enough room for buffers.@@DATA@@.TMP@@DATA@@.TMPCan not re-open work file.Previous work file garbled.@@DATA@@.TMP---------------- End of file. ----------------@@DATA@@.TMPb_lenb_ptrb_prefixdelete 1delete 2delete 3del_blbufins 1bufins 2bufinscombine 1combinecombine@@DATA@@.TMP@@DATA@@.TMPCan not open swap file.@@DATA@@.TMPDisk or directory full?Drive not ready?put_bufput_slotFile not found.Line split.swap_in 1swap_outswap_sync:can't happenIn check block 1.In Check block 2.In check block 3.line %3d, offset %3d, length %3d, total %3d: ^%c%c slot %2d, address %4lx, back %3d, diskp %3d, next %3d, lines %3d, lru %3d, status %3d, avail %3d start %d line %d, maxline %d head %d, tail %d, free %d, max_diskp %d a!vX _/aX` adeL$@`/aXe$@B"_a//8v!v!~/ <:aAa8$_$!v _Xa,``l  g aa,``V x< aag<@g<:faaa~g< f`!`tBAabg<ae_< QNu x"x< a6< a.c<:a"a6a2< ga`<@a< a< a<a`&t<<0<9c^aQNua*a, /a "_`f`^aJg/"@N _`NaR/CIE`$a2m$`&a,g` a&o`a n`af `Nual`NuBNupNu Nu "//a"NuaL-B`"aB+a"a:+/a"Ёi`a&-c/aD`a&a* /a"a`a/A/a "Aa`C2E|`xa*e"@B Nua JBfa( a&a)Nu`baB<@e>f&RHaЀeЀe/a"ct 8Nu< <e RH@@"8ANu(JjDJjDc Ab84H@H@B@Ђk&JjDNuJg$(JjDJjDv"BҁрgkRQAJjDDNua "@BNuaJgk""xrreC !ra RNuaJjDkNu 8Nuae:/a= a,_,Nu`&a~:X`~ar X`VNua  fNu/Maa _ 8vg~g B"xva 0 x \ & j D l 0 D 0 f , V Welcome to RED.DRI version 6.04 for CP/M 68K, May 20, 1985Copyright (C) 1985 by Edward K. Ream.Type ^c help for help.-- loading --load edit:insert:overtype:escape:verbatim:goto: kill:search:eXchange:command: Bad line number.changeclearcopydef0insdef0overdef0editdef1insdef1overdef1editdef2insdef2overdef2editdeletedosexitdumpextractfindrfindhelpinjectlistloadredmovenamenowrapresavesavesearchquitFile not named.tabswrapCommand not found.usage: copy -- copying ---- deleting --usage: extract first last-- extracting --Command Default args Descriptionchange 1 9999 Change all lines in clear Reset the editorcopy Copy lines in after line delete Delete one or more linesexit Exit from the editorextract Create a file from a blockfind Search for ddress %lx, back %d, diskp %d, next %d, avail %d, lines %d, lru %d, status %d Cannot open Cannot create CDOSUXcdosuxzhyyzXydzzhyyzXyhz z  !!!!"<?aB@Sa8`R/Mi`/MZ`a< aAag<g&<gD< g< eaȰ< g\e<a< ac<aS`"gSA<a< az<arQA`|< a^NudP"x$xSe JSAeNuT  f`޷g`Nug!`,_!g!!!!N"8d,_"8g/8/8/8/8/Ngaΰ< f< aNua"<""Ha I"_< gTNa'<'`a_ < a"_`Nu&?<JjDSD i ¼`0BAHA 42 HA2HAH@H@SDJfSDk < a.QJj<-ak <0a`8NuBIxa< aB@`aL"_gBNRRNBBBa0 0e( 9b" d ҁҁҀҁҀRB`Nu  fR`NuAB< g<"g<'gJfaR`NuJf`ֲfB`ΰ<ae <zb< NuaNg <f`NuMoga0`Nu9gNu9g 9<Nu9AgCNu9Ag 9C<NupNC Gordos MC68000 Tiny Basic, v1.1 ok how? what? sorry. **************************** cr = $0d ascii equates lf = $0a tab = $09 ctrlc = $03 ctrlh = $08 ctrls = $13 ctrlx = $18 esc = $1b writef = $15 write sequential readf = $14 read sequential openf = $0f open file closef = $10 close file deletef = $13 delete file createf = $16 create file setdma = $1a set DMA address fcb = $5c offset for default fcb in base page buflen = 80 length of keyboard input buffer * * standard jump table. you can change these addresses if you are * customizing this interpreter for a different environment. * start: bra cstart cold start entry point gowarm: bra wstart warm start entry point goout: bra outchr jump to character-out routine goin: bra inchr jump to character-in routine goauxo: bra auxout jump to auxiliary-out routine goauxi: bra auxin jump to auxiliary-in routine gobye: bra byebye jump to monitor, dos, etc. * * modifiable system constants: * txtbgn: .dc.l txt beginning of program memory endmem: .dc.l 0 end of availablelled area move.l a5,a2 points to beginning of move area bsr mvdown move things out of the way move.l a0,a1 set up to do the insertion move.l a5,a2 move.l a4,a3 bsr mvup do it bra st3 go back and get another line * ******************************************************************* * * *** tables *** direct *** exec *** * * this section of the code tests a string against a table. when * a match is found, control is transferred to the section of * code according to the table. * * at 'exec', a0 should point to the string, a1 should point to * the character table, and a2 should point to the execution * table. at 'direct', a0 should point to the string, a1 and * a2 will be set up to point to tab1 and tab1p1, which are * the tables of all direct and statement commands. * * a '.' in the string will terminate the test and the partial * match will be considered as a match, e.g. 'p.', 'pr.','pri.', * 'prin.', or 'print' will all match 'print'. * * there are two tables: the chara memory * * the main interpreter starts here: * cstart: move.l 4(sp),basepag save cp/m base page pointer move.l 4(sp),a0 get it to where we can use it move.l 4(a0),endmem top of the base page move.l 4(a0),sp initialize stack pointer lea initmsg,a6 tell who we are bsr prmesg move.l txtbgn,txtunf init. end-of-program pointer move.l endmem,d0 get address of end of memory sub.l #2048,d0 reserve 2k for the stack move.l d0,stklmt sub.l #108,d0 reserve variable area (27 long words) move.l d0,varbgn wstart: clr.l d0 initialize internal variables move.l d0,lopvar move.l d0,stkgos move.l d0,currnt current line number pointer = 0 move.l endmem,sp init s.p. again, just in case lea okmsg,a6 display "ok" bsr prmesg st3: move.b #'>',d0 prompt with a '>' and bsr getln read a line. bsr toupbuf convert to upper case move.l a0,a4 save pointer to end of line lea buffer,a0 point to the beginning of line bsr tstnum is there a number there? bsr ignblk skip trailing blanks cter table and the execution * table. the character table consists of any number of text items. * each item is a string of characters with the last character's * high bit set to one. the execution table holds a 16-bit * execution addresses that correspond to each entry in the * character table. * * the end of the character table is a 0 byte which corresponds * to the default routine in the execution table, which is * executed if none of the other table items are matched. * * character-matching tables: tab1: .dc.b 'LIS',('T'+$80) direct commands .dc.b 'LOA',('D'+$80) .dc.b 'NE',('W'+$80) .dc.b 'RU',('N'+$80) .dc.b 'SAV',('E'+$80) tab2: .dc.b 'NEX',('T'+$80) direct / statement .dc.b 'LE',('T'+$80) .dc.b 'I',('F'+$80) .dc.b 'GOT',('O'+$80) .dc.b 'GOSU',('B'+$80) .dc.b 'RETUR',('N'+$80) .dc.b 'RE',('M'+$80) .dc.b 'FO',('R'+$80) .dc.b 'INPU',('T'+$80) .dc.b 'PRIN',('T'+$80) .dc.b 'POK',('E'+$80) .dc.b 'CURSO',('R'+$80) added drl 25Mar86 .dc.b 'STO',('P'+$80) .dc.b '****************************************************************** * * * tiny basic for the motorola mc68000 * * * * derived from palo alto tiny basic as published in the may 1976 * * issue of dr. dobb's journal. adapted to the 68000 by: * * gordon brandly * * r.r. 2 * * fort sask., alberta, canada * * t8l 2n8 * * * * version 1.0 as of july 17, 1984 * * * * * * this version is for mex68kecb educational computer board i/o. * * * ****************************************************************** * copyright (c) 1984 by gordon brandly. this program may be * * freely distributed for personal use only. all commercial * * rights are reserved. * ****************************************************************** * CP/M-68K file and console I/O added by Dann Lunsford, * * Carmichael, CA, March 25, 1986 * ************************************** tst d1 does line no. exist? (or nonzero?) beq direct if not, it's a direct statement cmp.l #$ffff,d1 see if line no. is <= 16 bits bcc qhow if not, we've overflowed move.b d1,-(a0) store the binary line no. ror #8,d1 (kludge to store a word on a move.b d1,-(a0) possible byte boundary) rol #8,d1 bsr fndln find this line in save area move.l a1,a5 save possible line pointer bne st4 if not found, insert bsr fndnxt find the next line (into a1) move.l a5,a2 pointer to line to be deleted move.l txtunf,a3 points to top of save area bsr mvup move up to delete move.l a2,txtunf update the end pointer st4: move.l a4,d0 calculate the length of new line sub.l a0,d0 cmp.l #3,d0 is it just a line no. & cr? beq st3 if so, it was just a delete move.l txtunf,a3 compute new end move.l a3,a6 add.l d0,a3 move.l varbgn,d0 see if there's enough room cmp.l a3,d0 bls qsorry if not, say so move.l a3,txtunf if so, store new end position move.l a6,a1 points to old unfiBY',('E'+$80) .dc.b 'CAL',('L'+$80) .dc.b 0 tab4: .dc.b 'PEE',('K'+$80) functions .dc.b 'RN',('D'+$80) .dc.b 'AB',('S'+$80) .dc.b 'SIZ',('E'+$80) .dc.b 0 tab5: .dc.b 'T',('O'+$80) "to" in "for" .dc.b 0 tab6: .dc.b 'STE',('P'+$80) "step" in "for" .dc.b 0 .even * execution address tables: tab1p1: .dc.l list direct commands .dc.l load .dc.l new .dc.l run .dc.l save tab2p1: .dc.l next direct / statement .dc.l let .dc.l if .dc.l goto .dc.l gosub .dc.l return .dc.l rem .dc.l for .dc.l input .dc.l print .dc.l poke .dc.l cursor added drl 25Mar86 .dc.l stoprun .dc.l gobye .dc.l call .dc.l deflt tab4p1: .dc.l peek functions .dc.l rnd .dc.l abs .dc.l size .dc.l xp40 tab5p1: .dc.l fr1 "to" in "for" .dc.l qwhat tab6p1: .dc.l fr2 "step" in "for" .dc.l fr3 * direct: lea tab1,a1 lea tab1p1,a2 exec: bsr ignblk ignore leading blanks move.l a0,a3 save the pointer clr.b d2 clear match flag exlp: move.b (a0)+,d0 get the pr this line and executes it. * 'runsml' continues the execution on same line. * * 'goto expr' evaluates the expression, finds the target * line, and jumps to 'runtsl' to do it. * new: bsr endchk move.l txtbgn,txtunf set the end pointer stoprun: bsr endchk bra wstart run: bsr endchk move.l txtbgn,a0 set pointer to beginning move.l a0,currnt runnxl: tst.l currnt executing a program? beq wstart if not, we've finished a direct stat. clr.l d1 else find the next line number move.l a0,a1 move.l txtunf,a2 setup for search subq.l #1,a2 bsr fndlnp bcs wstart if we've fallen off the end, stop runtsl: move.l a1,currnt set currnt to point to the line no. move.l a1,a0 set the text pointer to addq.l #2,a0 the start of the line text runsml: bsr chkio see if a control-c was pressed lea tab2,a1 find command in tab2 lea tab2p1,a2 bra exec and execute it goto: bsr expr evaluate the following expression bsr endchk must find end of line move.l d0,d1 bsr fnn move d0,d4 and save it as print width bra pr3 look for more to print pr1: bsr qtstg is it a string? bra pr8 if not, must be an expression pr3: bsr ignblk if ",", go find next cmpi.b #',',(a0) bne pr6 addq.l #1,a0 bsr fin in the list. bra pr0 pr6: bsr crlf list ends here bra finish pr8: move d4,-(sp) save the width value bsr expr evaluate the expression move (sp)+,d4 restore the width move.l d0,d1 bsr prtnum print its value bra pr3 more to print? finish: bsr fin check end of command bra qwhat print "what?" if wrong * ******************************************************************* * * *** gosub *** & return *** * * 'gosub expr:' or 'gosub expr' is like the 'goto' command, * except that the current text pointer, stack pointer, etc. are * saved so that execution can be continued after the subroutine * 'return's. in order that 'gosub' can be nested (and even * recursive), the save area must be stacked. the stack pointer * is saved in 'stkgosogram character move.b (a1),d1 get the table character bne exngo if end of table, move.l a3,a0 restore the text pointer and... bra exgo execute the default. exngo: move.b d0,d3 else check for period... and.b d2,d3 and a match. cmp.b #'.',d3 beq exgo if so, execute and.b #$7f,d1 ignore the table's high bit cmp.b d0,d1 is there a match? beq exmat addq.l #4,a2 if not, try the next entry move.l a3,a0 reset the program pointer clr.b d2 sorry, no match ex1: tst.b (a1)+ get to the end of the entry bpl ex1 bra exlp back for more matching exmat: moveq #-1,d2 we've got a match so far tst.b (a1)+ end of table entry? bpl exlp if not, go back for more exgo: move.l (a2),a3 execute the appropriate routine jmp (a3) * ******************************************************************* * * what follows is the code to execute direct and statement * commands. control is transferred to these points via the command * table lookup code of 'direct' and 'exec' in the lasdln find the target line bne qhow no such line no. bra runtsl go do it * ******************************************************************* * * *** list *** print *** * * list has two forms: * 'list' lists all saved lines * 'list #' starts listing at the line # * control-s pauses the listing, control-c stops it. * * print command is 'print ....:' or 'print ....' * where '....' is a list of expressions, formats, back-arrows, * and strings. these items a separated by commas. * * a format is a pound sign followed by a number. it controls * the number of spaces the value of an expression is going to * be printed in. it stays effective for the rest of the print * command unless changed by another format. if no format is * specified, 11 positions will be used. * * a string is quoted in a pair of single- or double-quotes. * * an underline (back-arrow) means generate a without a * * a is generated after the entire list has been printed * or if the '. the old 'stkgos' is saved on the stack. * if we are in the main routine, 'stkgos' is zero (this was done * in the initialization section of the interpreter), but we still * save it as a flag for no further 'return's. * * 'return' undoes everything that 'gosub' did, and thus * returns the execution to the command after the most recent * 'gosub'. if 'stkgos' is zero, it indicates that we never had * a 'gosub' and is thus an error. * gosub: bsr pusha save the current 'for' parameters bsr expr get line number move.l a0,-(sp) save text pointer move.l d0,d1 bsr fndln find the target line bne ahow if not there, say "how?" move.l currnt,-(sp) found it, save old 'currnt'... move.l stkgos,-(sp) and 'stkgos' clr.l lopvar load new values move.l sp,stkgos bra runtsl return: bsr endchk there should be just a move.l stkgos,d1 get old stack pointer beq qwhat if zero, it doesn't exist move.l d1,sp else restore it move.l (sp)+,stkgos and the old 'stkgos' move.l (t section. * after the command is executed, control is transferred to other * sections as follows: * * for 'list', 'new', and 'stop': go back to the warm start point. * for 'run': go execute the first stored line if any; else go * back to the warm start point. * for 'goto' and 'gosub': go execute the target line. * for 'return' and 'next'; go back to saved return line. * for all others: if 'currnt' is 0, go to warm start; else go * execute next command. (this is done in 'finish'.) * ******************************************************************* * * *** new *** stop *** run (& friends) *** goto *** * * 'new' sets txtunf to point to txtbgn * * 'stop' goes back to wstart * * 'run' finds the first stored line, stores its address * in currnt, and starts executing it. note that only those * commands in tab2 are legal for a stored program. * * there are 3 more entries in 'run': * 'runnxl' finds next line, stores it's address and executes it. * 'runtsl' stores the address oflist is empty. if the list ends with a semicolon, * however, no is generated. * list: bsr tstnum see if there's a line no. bsr endchk if not, we get a zero bsr fndln find this or next line ls1: bcs wstart warm start if we passed the end bsr prtln print the line bsr chkio check for listing halt request beq ls3 cmp.b #ctrls,d0 pause the listing? bne ls3 ls2: bsr chkio if so, wait for another keypress beq ls2 ls3: move.l txtunf,a2 setup for search subq.l #1,a2 bsr fndlnp find the next line bra ls1 print: move #11,d4 d4 = number of print spaces bsr ignblk if null list and ":" cmpi.b #':',(a0) bne pr2 addq.l #1,a0 bsr crlf give cr-lf and continue bra runsml execution on the same line pr2: bsr ignblk if null list and cmpi.b #cr,(a0) bne pr0 addq.l #1,a0 bsr crlf also give cr-lf and bra runnxl execute the next line pr0: bsr ignblk else is it a format? cmpi.b #'#',(a0) bne pr1 addq.l #1,a0 bsr expr yes, evaluate expressiosp)+,currnt and the old 'currnt' move.l (sp)+,a0 and the old text pointer bsr popa and the old 'for' parameters bra finish and we are back home * ******************************************************************* * * *** for *** & next *** * * 'for' has two forms: * 'for var=exp1 to exp2 step exp1' and 'for var=exp1 to exp2' * the second form means the same thing as the first form with a * step of positive 1. the interpreter will find the variable 'var' * and set its value to the current value of 'exp1'. it also * evaluates 'exp2' and 'exp1' and saves all these together with * the text pointer, etc. in the 'for' save area, which consisits of * 'lopvar', 'lopinc', 'loplmt', 'lopln', and 'loppt'. if there is * already something in the save area (indicated by a non-zero * 'lopvar'), then the old save area is saved on the stack before * the new values are stored. the interpreter will then dig in the * stack and find out if this same variable was used in another * currently active d0 get control variable's value add.l lopinc,d0 add in loop increment bvs qhow say "how?" for 32-bit overflow move.l d0,(a1) save control variable's new value move.l loplmt,d1 get loop's limit value tst.l lopinc bpl nx1 branch if loop increment is positive exg d0,d1 nx1: cmp.l d0,d1 test against limit blt nx2 branch if outside limit move.l lopln,currnt within limit, go back to the... move.l loppt,a0 saved 'currnt' and text pointer. bra finish nx2: bsr popa purge this loop bra finish * ******************************************************************* * * *** rem *** if *** input *** let (& deflt) *** * * 'rem' can be followed by anything and is ignored by the * interpreter. * * 'if' is followed by an expression, as a condition and one or * more commands (including other 'if's) separated by colons. * note that the word 'then' is not used. the interpreter evaluates * the expression. if it is non-zero, execution continues. if it * is zero, the commands that folstg' bsr tstv must be a variable now bcs qwhat "what?" it isn't? move.l d0,a2 put away the variable's address move.b (a0),d2 get ready for 'prtstg' clr.b d0 move.b d0,(a0) move.l (sp)+,a1 bsr prtstg print string as prompt move.b d2,(a0) restore text ip3: move.l a0,-(sp) save in case of error move.l currnt,-(sp) also save 'currnt' move.l #-1,currnt flag that we are in input move.l sp,stkinp save the stack pointer too move.l a2,-(sp) save the variable address move.b #':',d0 print a colon first bsr getln then get an input line lea buffer,a0 point to the buffer bsr expr evaluate the input move.l (sp)+,a2 restore the variable address move.l d0,(a2) save value in variable move.l (sp)+,currnt restore old 'currnt' move.l (sp)+,a0 and the old text pointer ip4: addq.l #4,sp clean up the stack bsr ignblk is the next thing a comma? cmpi.b #',',(a0) bne finish addq.l #1,a0 bra input yes, more items deflt: cmp.b #cr,(a0) empty line is ok beq finish el'for' loop. if that is the case, then the old * 'for' loop is deactivated. (i.e. purged from the stack) * * 'next var' serves as the logical (not necessarily physical) end * of the 'for' loop. the control variable 'var' is checked with * the 'lopvar'. if they are not the same, the interpreter digs in * the stack to find the right one and purges all those that didn't * match. either way, it then adds the 'step' to that variable and * checks the result with against the limit value. if it is within * the limit, control loops back to the command following the * 'for'. if it's outside the limit, the save area is purged and * execution continues. * for: bsr pusha save the old 'for' save area bsr setval set the control variable move.l a6,lopvar save its address lea tab5,a1 use 'exec' to test for 'to' lea tab5p1,a2 bra exec fr1: bsr expr evaluate the limit move.l d0,loplmt save that lea tab6,a1 use 'exec' to look for the lea tab6p1,a2 word 'step' bra exec fr2: bsr expr foulow are ignored and execution * continues on the next line. * * 'input' is like the 'print' command, and is followed by a list * of items. if the item is a string in single or double quotes, * or is an underline (back arrow), it has the same effect as in * 'print'. if an item is a variable, this variable name is * printed out followed by a colon, then the interpreter waits for * an expression to be typed in. the variable is then set to the * value of this expression. if the variable is preceeded by a * string (again in single or double quotes), the string will be * displayed followed by a colon. the interpreter the waits for an * expression to be entered and sets the variable equal to the * expression's value. if the input expression is invalid, the * interpreter will print "what?", "how?", or "sorry" and reprint * the prompt and redo the input. the execution will not terminate * unless you press control-c. this is handled in 'inperr'. * * 'let' is followed by a list of items separatse it is 'let' let: bsr setval do the assignment bsr ignblk check for more 'let' items cmpi.b #',',(a0) bne finish addq.l #1,a0 bra let * ******************************************************************* * * *** load *** & save *** * * These commands save and restore a program to/from CP/M-68K disk files. * Syntax is: * LOAD FILENAME * SAVE FILENAME * Limitations are (currently) that the file type is forced to TBI, and * that the filename is not checked extensively for validity. The format * of a saved BASIC program file is a one-sector header, which contains in * its first four bytes, the length of the program's core image. The * remaining sectors of the file are a core image of the program space * (line numbers in binary, CR only at end of line). This is easiest * to program. It does, however, preclude the use of a full-screen editor * for program preparation. Think about building one for this BASIC. * Dann Lunsford, 25Mar86 * load: bsr ignblk move.l basepag,nd it, get the step value bra fr4 fr3: moveq #1,d0 not found, step defaults to 1 fr4: move.l d0,lopinc save that too fr5: move.l currnt,lopln save address of current line number move.l a0,loppt and text pointer move.l sp,a6 dig into the stack to find 'lopvar' bra fr7 fr6: add.l #20,a6 look at next stack frame fr7: move.l (a6),d0 is it zero? beq fr8 if so, we're done cmp.l lopvar,d0 same as current lopvar? bne fr6 nope, look some more move.l sp,a2 else remove 5 long words from... move.l a6,a1 inside the stack. lea 20,a3 add.l a1,a3 bsr mvdown move.l a3,sp set the sp 5 long words up fr8: bra finish and continue execution next: bsr tstv get address of variable bcs qwhat if no variable, say "what?" move.l d0,a1 save variable's address nx0: move.l lopvar,d0 if 'lopvar' is zero, we never... beq qwhat had a for loop, so say "what?" cmp.l d0,a1 else we check them beq nx3 ok, they agree bsr popa nope, let's see the next frame bra nx0 nx3: move.l (a1),ed by commas. * each item consists of a variable, an equals sign, and an * expression. the interpreter evaluates the expression and sets * the variable to that value. the interpreter will also handle * 'let' commands without the word 'let'. this is done by 'deflt'. * rem: bra if2 skip the rest of the line if: bsr expr evaluate the expression if1: tst.l d0 is it zero? bne runsml if not, continue if2: move.l a0,a1 clr.l d1 bsr fndskp if so, skip the rest of the line bcc runtsl and run the next line bra wstart if no next line, do a warm start inperr: move.l stkinp,sp restore the old stack pointer move.l (sp)+,currnt and old 'currnt' addq.l #4,sp move.l (sp)+,a0 and old text pointer input: move.l a0,-(sp) save in case of error bsr qtstg is next item a string? bra ip2 nope bsr tstv yes, but is it followed by a variable? bcs ip4 if not, branch move.l d0,a2 put away the variable's address bra ip3 if so, input to variable ip2: move.l a0,-(sp) save for 'prta6 lea fcb(a6),a5 bsr fcbset bcs qwhat lea $80(a6),a6 move.l a6,d1 moveq #setdma,d0 trap #2 move.l a5,d1 moveq #openf,d0 trap #2 tst.b d0 bmi qhow clr.b 32(a5) move.l a5,d1 moveq #readf,d0 trap #2 read header sector tst.b d0 bne qsorry move.l (a6),d4 save program length move.l txtbgn,a6 .rloop: move.l a6,d1 moveq #setdma,d0 trap #2 set buffer addr move.l a5,d1 moveq #readf,d0 trap #2 read one sector's worth of program tst.b d0 bne .rclose lea 128(a6),a6 bra .rloop .rclose: move.l txtbgn,d0 add.l d4,d0 cmpa.l d0,a6 blt qsorry move.l d0,txtunf bra wstart save: move.l txtunf,d5 compute length of program sub.l txtbgn,d5 cmpi.l #5,d5 smallest possible valid program bcs qsorry unable to comply bsr ignblk skip blanks in command move.l basepag,a6 use default fcb lea fcb(a6),a5 point at it bsr fcbset a0 points at string, a5 at fcb bcs qwhat bad filename move.l a5,d1 set up for system call moveq #deletef,d0 deleess specified by 'expr1'. * * 'call expr' jumps to the machine language subroutine whose * starting address is specified by 'expr'. the subroutine can use * all registers but must leave the stack the way it found it. * the subroutine returns to the interpreter by executing an rts. * * 'cursor expr1,expr2' positions the cursor on the terminal screen * expr1 is the row co-ordinate, and expr2 is the column. * note: No checking is done for proper range of row or column. * Contains terminal dependent code, must be altered if ported to * a different terminal. * poke: bsr expr get the memory address bsr ignblk it must be followed by a comma cmpi.b #',',(a0) bne qwhat addq.l #1,a0 move.l d0,-(sp) save the address bsr expr get the byte to be poke'd move.l (sp)+,a1 get the address back move.b d0,(a1) store the byte in memory bra finish cursor: bsr expr get the row coord bsr ignblk must be followed by a comma cmpi.b #',',(a0) bne qwhat addq.l #1,a0 move.b d0,-(sp) savebge xprt0 if not, return d0=0 bra xprt1 else return d0=1 xp16rt: rts xprt0: clr.l d0 return d0=0 (false) rts xprt1: moveq #1,d0 return d0=1 (true) rts * added per ddj #106 xxp2: cmpi.b #'=',(a0) <=? bne xxp3 no addq.l #1,a0 bra xp14 process <= xxp3: cmpi.b #'>',(a0) <>? bne xp16 no, process < addq.l #1,a0 skip past > bra xp12 process <> xxp1: cmpi.b #'<',d2 <, <=, or <>? beq xxp2 no subq.l #1,a0 default case, so drop through and handle xp17: move.l (sp)+,d0 it's not a rel. operator rts return d0= xp18: move.l (sp)+,d0 reverse the top two stack items move.l (sp)+,d1 move.l d0,-(sp) move.l d1,-(sp) bsr expr2 do second move.l (sp)+,d1 cmp.l d0,d1 compare with the first result rts return the result expr2: bsr ignblk negative sign? cmpi.b #'-',(a0) bne xp21 addq.l #1,a0 clr.l d0 yes, fake '0-' bra xp26 xp21: bsr ignblk positive sign? ignore it cmpi.b #'+',(a0) bne xp22 addq.l #1,a0 xp22: bsr expr3 first <te old file if present trap #2 move.l a5,d1 set up for create moveq #createf,d0 trap #2 tst.b d0 bmi qhow can't create clr.b 32(a5) set current record field, file is open lea $80(a6),a6 point at default buffer move.l a6,d1 but it might have been changed moveq #setdma,d0 trap #2 move.l d5,(a6) set length into header record move.l a5,d1 moveq #writef,d0 trap #2 write header tst d0 bne closfile move.l txtbgn,a6 beginning of program buffer sloop: move.l a6,d1 set dma moveq #setdma,d0 trap #2 move.l a5,d1 moveq #writef,d0 trap #2 write program block tst d0 bne closfile lea 128(a6),a6 bump dma pointer cmpa.l txtunf,a6 done? bls sloop no, go write next record closfile: move.l a5,d1 moveq #closef,d0 trap #2 tst.b d0 bmi qhow bra wstart * fcbset builds a CP/M-68K FCB in the place that a5 points at, out * of the string that a0 points at. File type is forced to TBI. * returns C set if something is uncool. A5 is unchanged on return row bsr expr get column move.b d0,-(sp) save column moveq #$1b,d0 cursor position lead in bsr goout moveq #$3d,d0 bsr goout moveq #$20,d0 add.b 2(sp),d0 bsr goout moveq #$20,d0 add.b (sp),d0 bsr goout tst.l (sp)+ bra finish call: bsr expr get the subroutine's address tst.l d0 make sure we got a valid address beq qhow if not, say "how?" move.l a0,-(sp) save the text pointer move.l d0,a1 jsr (a1) jump to the subroutine move.l (sp)+,a0 restore the text pointer bra finish * ******************************************************************* * * *** expr *** * * 'expr' evaluates arithmetical or logical expressions. * ::= * * where is one of the operators in tab8 and the result * of these operations is 1 if true and 0 if false. * ::=(+ or -)(+ or -)(... * where () are optional and (... are optional repeats. * ::=( <* or /> )(... * ::= expr3> xp23: bsr ignblk add? cmpi.b #'+',(a0) bne xp25 addq.l #1,a0 move.l d0,-(sp) yes, save the value bsr expr3 get the second xp24: move.l (sp)+,d1 add.l d1,d0 add it to the first bvs qhow branch if there's an overflow bra xp23 else go back for more operations xp25: bsr ignblk subtract? cmpi.b #'-',(a0) bne xp42 addq.l #1,a0 xp26: move.l d0,-(sp) yes, save the result of 1st bsr expr3 get second neg.l d0 change its sign jmp xp24 and do an addition expr3: bsr expr4 get first xp31: bsr ignblk multiply? cmpi.b #'*',(a0) bne xp34 addq.l #1,a0 move.l d0,-(sp) yes, save that first result bsr expr4 get second move.l (sp)+,d1 bsr mult32 multiply the two bra xp31 then look for more terms xp34: bsr ignblk divide? cmpi.b #'/',(a0) bne xp42 addq.l #1,a0 move.l d0,-(sp) save result of 1st bsr expr4 get second move.l (sp)+,d1 exg d0,d1 bsr div32 do the division bra xp31  * a0 has been advanced to point to the last valid char for the fcb fcbset: move.l a5,a1 moveq #32-1,d0 .cloop: clr.b (a1)+ dbra d0,.cloop move.b #'T',9(a5) move.b #'B',10(a5) move.b #'I',11(a5) move.l a5,a1 cmpi.b #':',1(a0) drive present? bne .fcbs1 nope move.b (a0),d0 subi.b #'A',d0 whole buffer was touppered, remember? bcs .fcbex whoops! cmpi.b #'P'-'A'+1,d0 eori #1,ccr bcs .fcbex move.b d0,(a1)+ store drive addq.l #2,a0 bump past D: bra .fcbs2 .fcbs1: addq.l #1,a1 .fcbs2: moveq #8-1,d0 8 chars max .fcbs3: move.b (a0)+,d1 get char cmpi.b #cr,d1 end of line? beq .fcbol yep cmpi.b #'.',d1 alien filetype? beq .fcbol move.b d1,(a1)+ dbra d0,.fcbs3 .fcbol: cmpi #-1,d0 beq .fcbex .fcbl1: move.b #$20,(a1)+ fill in rest of fcb dbra d0,.fcbl1 .fcbex: rts * ******************************************************************* * * *** poke *** & call *** & cursor *** * * 'poke expr1,expr2' stores the byte from 'expr2' into the memory * addr* * () * is recursive so that the variable '@' can have an * as an index, functions can have an as arguments, and * can be an in parenthesis. * expr: bsr expr2 move.l d0,-(sp) save value * added per ddj #106 bsr ignblk skip blanks move.b (a0)+,d2 get first char cmpi.b #'=',d2 equals beq xp15 yes, go process * cmpi.b #'>',d2 >, or >=? bne xxp1 no * cmpi.b #'=',(a0) >=? bne xp13 no, process > * addq.l #1,a0 skip past = xp11: bsr xp18 is it ">="? blt xprt0 no, return d0=0 bra xprt1 else return d0=1 xp12: bsr xp18 is it "<>"? beq xprt0 no, return d0=0 bra xprt1 else return d0=1 xp13: bsr xp18 is it ">"? ble xprt0 no, return d0=0 bra xprt1 else return d0=1 xp14: bsr xp18 is it "<="? bgt xprt0 no, return d0=0 bra xprt1 else return d0=1 xp15: bsr xp18 is it "="? bne xprt0 if not, return d0=0 bra xprt1 else return d0=1 xp15rt: rts xp16: bsr xp18 is it "<"? go back for any more terms expr4: lea tab4,a1 find possible function lea tab4p1,a2 bra exec xp40: bsr tstv nope, not a function bcs xp41 nor a variable move.l d0,a1 clr.l d0 move.l (a1),d0 if a variable, return its value in d0 exp4rt: rts xp41: bsr tstnum or is it a number? move.l d1,d0 tst d2 (if not, # of digits will be zero) bne exp4rt if so, return it in d0 parn: bsr ignblk else look for ( expr ) cmpi.b #'(',(a0) bne qwhat addq.l #1,a0 bsr expr bsr ignblk cmpi.b #')',(a0) bne qwhat addq.l #1,a0 xp42: rts * * ===== test for a valid variable name. returns carry=1 if not * found, else returns carry=0 and the address of the * variable in d0. tstv: bsr ignblk clr.l d0 move.b (a0),d0 look at the program text sub.b #'@',d0 bcs tstvrt c=1: not a variable bne tv1 branch if not "@" array addq #1,a0 if it is, it should be bsr parn followed by (expr) as its index. add.l d0,d0 bcs qhow say "how?" if index is too big add.l d0,d0 bcs: add.l d1,d1 (this algorithm was translated from addx.l d0,d0 the divide routine in ron cain's beq div4 small-c run time library.) cmp.l d2,d0 bmi div4 addq.l #1,d1 sub.l d2,d0 div4: dbra d3,div3 exg d0,d1 put rem. & quot. in proper registers tst.l d4 were the signs the same? bpl divrt neg.l d0 if not, results are negative neg.l d1 divrt: rts * * ===== the peek function returns the byte stored at the address * contained in the following expression. * peek: bsr parn get the memory address move.l d0,a1 clr.l d0 upper 3 bytes will be zero move.b (a1),d0 get the addressed byte rts and return it * * ===== the rnd function returns a random number from 1 to * the value of the following expression in d0. * rnd: bsr parn get the upper limit tst.l d0 it must be positive and non-zero beq qhow bmi qhow move.l d0,d1 move.l ranpnt,a1 get memory as a random number cmp.l #lstrom,a1 bcs ra1 lea start,a1 wrap around if end of program ra1: move.l (a1)+l: bsr tstv variable name? bcs qwhat if not, say "what?" move.l d0,-(sp) save the variable's address bsr ignblk get past the "=" sign cmpi.b #'=',(a0) bne qwhat addq.l #1,a0 bsr expr evaluate the expression move.l (sp)+,a6 move.l d0,(a6) and save its value in the variable rts fin: bsr ignblk *** fin *** cmpi.b #':',(a0) bne fi1 addq.l #1,a0 addq.l #4,sp if ":", discard return address bra runsml continue on the same line fi1: bsr ignblk not ":", is it a cr? cmpi.b #cr,(a0) bne fi2 addq.l #1,a0 addq.l #4,sp yes, purge return address bra runnxl execute the next line fi2: rts else return to the caller endchk: bsr ignblk cmp.b #cr,(a0) does it end with a cr? bne qwhat if not, say "what?" rts qwhat: move.l a0,-(sp) awhat: lea whtmsg,a6 error: bsr prmesg display the error message move.l (sp)+,a0 restore the text pointer move.l currnt,d0 get the current line number beq wstart if zero, do a warm start cmp.l #-1,d0 is the line no. point qhow move.l d0,-(sp) save the index bsr size get amount of free memory move.l (sp)+,d1 get back the index cmp.l d1,d0 see if there's enough memory bls qsorry if not, say "sorry" move.l varbgn,d0 put address of array element... sub.l d1,d0 into d0 rts tv1: cmp.b #27,d0 if not @, is it a through z? eori #1,ccr bcs tstvrt if not, set carry and return addq #1,a0 else bump the text pointer add d0,d0 compute the variable's address add d0,d0 move.l varbgn,d1 add d1,d0 and return it in d0 with carry=0 tstvrt: rts * * ===== multiplies the 32 bit values in d0 and d1, returning * the 32 bit result in d0. * mult32: move.l d1,d4 eor.l d0,d4 see if the signs are the same tst.l d0 take absolute value of d0 bpl mlt1 neg.l d0 mlt1: tst.l d1 take absolute value of d1 bpl mlt2 neg.l d1 mlt2: cmp.l #$ffff,d1 is second argument <= 16 bits? bls mlt3 ok, let it through exg d0,d1 else swap the two arguments cmp.l #$ffff,d1 and check 2nd argument again bhi qh,d0 get the slightly random number bclr #31,d0 make sure it's positive move.l a1,ranpnt (even i can do better than this!) bsr div32 rnd(n)=mod(number,n)+1 move.l d1,d0 mod is the remainder of the div. addq.l #1,d0 rts * * ===== the abs function returns an absolute value in d0. * abs: bsr parn get the following expr.'s value tst.l d0 bpl absrt neg.l d0 if negative, complement it bmi qhow if still negative, it was too big absrt: rts * * ===== the size function returns the size of free memory in d0. * size: move.l varbgn,d0 get the number of free bytes... sub.l txtunf,d0 between 'txtunf' and 'varbgn' rts return the number in d0 * ******************************************************************* * * *** setval *** fin *** endchk *** error (& friends) *** * * 'setval' expects a variable, followed by an equal sign and then * an expression. it evaluates the expression and sets the variable * to that value. * * 'fin' checks the end of a command. if it endeder = -1? beq inperr if so, redo input move.b (a0),-(sp) save the char. pointed to clr.b (a0) put a zero where the error is move.l currnt,a1 point to start of current line bsr prtln display the line in error up to the 0 move.b (sp)+,(a0) restore the character move.b #'?',d0 display a "?" bsr goout clr d0 subq.l #1,a1 point back to the error char. bsr prtstg display the rest of the line bra wstart and do a warm start qsorry: move.l a0,-(sp) asorry: lea srymsg,a6 bra error qhow: move.l a0,-(sp) error: "how?" ahow: lea howmsg,a6 bra error * ******************************************************************* * * *** getln *** fndln (& friends) *** * * 'getln' reads in input line into 'buffer'. it first prompts with * the character in d0 (given by the caller), then it fills the * buffer and echos. it ignores lf's but still echos * them back. control-h is used to delete the last character * entered (if there is one), and control-x is used to delete the * whole line aow one of them must be 16 bits mlt3: move d0,d2 prepare for 32 bit x 16 bit multiply mulu d1,d2 multiply low word swap d0 mulu d1,d0 multiply high word swap d0 *********** multiply overflow fix ********** rev 1.1 tst d0 test for overflow bne qhow add.l d2,d0 d0 now holds the product * if sign bit set after add then overflow bmi qhow if overflow, say "how?" ******************************************** tst.l d4 were the signs the same? bpl mltret neg.l d0 if not, make the result negative mltret: rts * * ===== divide the 32 bit value in d0 by the 32 bit value in d1. * returns the 32 bit quotient in d0, remainder in d1. * div32: tst.l d1 check for divide-by-zero beq qhow if so, say "how?" move.l d1,d2 move.l d1,d4 eor.l d0,d4 see if the signs are the same tst.l d0 take absolute value of d0 bpl div1 neg.l d0 div1: tst.l d1 take absolute value of d1 bpl div2 neg.l d1 div2: moveq #31,d3 iteration count for 32 bits move.l d0,d1 clr.l d0 div3 with ":", * execution continues. if it ended with a cr, it finds the * the next line and continues from there. * * 'endchk' checks if a command is ended with a cr. this is * required in certain commands, such as goto, return, stop, etc. * * 'error' prints the string pointed to by a0. it then prints the * line pointed to by currnt with a "?" inserted at where the * old text pointer (should be on top of the stack) points to. * execution of tiny basic is stopped and a warm start is done. * if currnt is zero (indicating a direct command), the direct * command is not printed. if currnt is -1 (indicating * 'input' command in progress), the input line is not printed * and execution is not terminated but continues at 'inperr'. * * related to 'error' are the following: * 'qwhat' saves text pointer on stack and gets "what?" message. * 'awhat' just gets the "what?" message and jumps to 'error'. * 'qsorry' and 'asorry' do the same kind of thing. * 'qhow' and 'ahow' also do this for "how?". * setvand start over again. cr signals the end of a line, * and causes 'getln' to return. * * 'fndln' finds a line with a given line no. (in d1) in the * text save area. a1 is used as the text pointer. if the line * is found, a1 will point to the beginning of that line * (i.e. the high byte of the line no.), and flags are nc & z. * if that line is not there and a line with a higher line no. * is found, a1 points there and flags are nc & nz. if we reached * the end of the text save area and cannot find the line, flags * are c & nz. * 'fndln' will initialize a1 to the beginning of the text save * area to start the search. some other entries of this routine * will not initialize a1 and do the search. * 'fndlnp' will start with a1 and search for the line no. * 'fndnxt' will bump a1 by 2, find a cr and then start search. * 'fndskp' uses a1 to find a cr, and then starts the search. * getln: bsr goout display the prompt move.b #' ',d0 and a space bsr goout lea buffer,a0 a0 is the buffer pointer  to where a2 points * until a1=a3 * * 'mvdown' moves a block down from where a1 points to where a3 * points until a1=a2 * * 'popa' restores the 'for' loop variable save area from the stack * * 'pusha' stacks for 'for' loop variable save area onto the stack * mvup: cmp.l a1,a3 see the above description beq mvret move.b (a1)+,(a2)+ bra mvup mvret: rts mvdown: cmp.l a1,a2 see the above description beq mvret move.b -(a1),-(a3) bra mvdown popa: move.l (sp)+,a6 a6 = return address move.l (sp)+,lopvar restore lopvar, but zero means no more beq pp1 move.l (sp)+,lopinc if not zero, restore the rest move.l (sp)+,loplmt move.l (sp)+,lopln move.l (sp)+,loppt pp1: jmp (a6) return pusha: move.l stklmt,d1 are we running out of stack room? sub.l sp,d1 bcc qsorry if so, say we're sorry move.l (sp)+,a6 else get the return address move.l lopvar,d1 save loop variables beq pu1 if lopvar is zero, that's all move.l loppt,-(sp) else save all the others move.l lopln,-(spne? cmpi.b #'_',(a0) bne qt5 addq.l #1,a0 move.b #cr,d0 if so, output a cr without lf bsr goout move.l (sp)+,a1 pop return address bra qt2 qt5: rts none of the above prtnum: move.l d1,d3 save the number for later move d4,-(sp) save the width value move.b #$ff,-(sp) flag for end of digit string tst.l d1 is it negative? bpl pn1 if not neg.l d1 else make it positive subq #1,d4 one less for width count pn1: divu #10,d1 get the next digit bvs pnov overflow flag set? move.l d1,d0 if not, save remainder and.l #$ffff,d1 strip the remainder bra toascii skip the overflow stuff pnov: move d1,d0 prepare for long word division clr.w d1 zero out low word swap d1 high word into low divu #10,d1 divide high word move d1,d2 save quotient move d0,d1 low word into low divu #10,d1 divide low word move.l d1,d0 d0 = remainder swap d1 r/q becomes q/r move d2,d1 d1 is low/high swap d1 d1 is finally high/low toascii: swap d0 get remainder move.b d0,gl1: bsr chkio check keyboard beq gl1 wait for a char. to come in cmp.b #ctrlh,d0 delete last character? beq gl3 if so cmp.b #ctrlx,d0 delete the whole line? beq gl4 if so cmp.b #cr,d0 accept a cr beq gl2 cmp.b #' ',d0 if other control char., discard it bcs gl1 gl2: move.b d0,(a0)+ save the char. bsr goout echo the char back out cmp.b #cr,d0 if it's a cr, end the line beq gl7 cmp.l #(buffer+buflen-1),a0 any more room? bcs gl1 yes: get some more, else delete last char. gl3: move.b #ctrlh,d0 delete a char. if possible bsr goout move.b #' ',d0 bsr goout cmp.l #buffer,a0 any char.'s left? bls gl1 if not move.b #ctrlh,d0 if so, finish the bs-space-bs sequence bsr goout subq.l #1,a0 decrement the text pointer bra gl1 back for more gl4: move.l a0,d1 delete the whole line sub.l #buffer,d1 figure out how many backspaces we need beq gl6 if none needed, branch subq #1,d1 adjust for dbra gl5: move.b #ctrlh,d0 and display bs-space-bs sequences bsr g) move.l loplmt,-(sp) move.l lopinc,-(sp) pu1: move.l d1,-(sp) jmp (a6) return * ******************************************************************* * * *** prtstg *** qtstg *** prtnum *** prtln *** * * 'prtstg' prints a string pointed to by a1. it stops printing * and returns to the caller when either a cr is printed or when * the next byte is the same as what was passed in d0 by the * caller. * * 'qtstg' looks for an underline (back-arrow on some systems), * single-quote, or double-quote. if none of these are found, returns * to the caller. if underline, outputs a cr without a lf. if single * or double quote, prints the quoted string and demands a matching * end quote. after the printing, the next 2 bytes of the caller are * skipped over (usually a short branch instruction). * * 'prtnum' prints the 32 bit number in d1, leading blanks are added if * needed to pad the number of spaces to the number in d4. * however, if the number of digits is larger than the no. in * d4, all-(sp) stack it as a digit swap d0 subq #1,d4 decrement width count tst.l d1 if quotient is zero, we're done bne pn1 subq #1,d4 adjust padding count for dbra bmi pn4 skip padding if not needed pn3: move.b #' ',d0 display the required leading spaces bsr goout dbra d4,pn3 pn4: tst.l d3 is number negative? bpl pn5 move.b #'-',d0 if so, display the sign bsr goout pn5: move.b (sp)+,d0 now unstack the digits and display bmi pnret until the flag code is reached add.b #'0',d0 make into ascii bsr goout bra pn5 pnret: move (sp)+,d4 restore width value rts prtln: clr.l d1 move.b (a1)+,d1 get the binary line number lsl #8,d1 move.b (a1)+,d1 moveq #5,d4 display a 5 digit line no. bsr prtnum move.b #' ',d0 followed by a blank bsr goout clr d0 stop char. is a zero bra prtstg display the rest of the line * * ===== see if the text pointed to by a0 is a number. if so, * return the number in d1 and the number of digits in d2, * else return zero in d1 andoout move.b #' ',d0 bsr goout move.b #ctrlh,d0 bsr goout dbra d1,gl5 gl6: lea buffer,a0 reinitialize the text pointer bra gl1 and go back for more gl7: move.b #lf,d0 echo a lf for the cr bsr goout rts fndln: cmp.l #$ffff,d1 line no. must be < 65535 bcc qhow move.l txtbgn,a1 init. the text save pointer move.l txtunf,a2 check if we passed the end subq.l #1,a2 fndlnp: cmp.l a1,a2 change per ddj #106 bcs fndret if so, return with z=0 & c=1 move.b (a1),d2 if not, get a line no. lsl.l #8,d2 move.b 1(a1),d2 cmp d1,d2 is this the line we want? bcc fndret no, not there yet f1: addq.l #2,a1 f2: cmpi.b #cr,(a1)+ bne f2 bra fndlnp fndret: rts return the cond. codes fndnxt: move.l txtunf,a2 subq.l #1,a2 find the next line bra f1 fndskp: move.l txtunf,a2 subq.l #1,a2 bra f2 * ******************************************************************* * * *** mvup *** mvdown *** popa *** pusha *** * * 'mvup' moves a block up from where a1 points digits are printed anyway. negative sign is also * printed and counted in, positive sign is not. * * 'prtln' prints the saved text line pointed to by a1 * with line no. and all. * prtstg: move.b d0,d1 save the stop character ps1: move.b (a1)+,d0 get a text character cmp.b d0,d1 same as stop character? beq prtret if so, return bsr goout display the char. cmp.b #cr,d0 is it a c.r.? bne ps1 no, go back for more move.b #lf,d0 yes, add a l.f. bsr goout prtret: rts then return qtstg: bsr ignblk *** qtstg *** cmpi.b #'"',(a0) bne qt3 addq.l #1,a0 move.b #'"',d0 it is a " qt1: move.l a0,a1 bsr prtstg print until another move.l a1,a0 move.l (sp)+,a1 pop return address cmp.b #lf,d0 was last one a cr? beq runnxl if so, run next line qt2: addq.l #2,a1 skip 2 bytes on return jmp (a1) return qt3: bsr ignblk is it a single quote? cmpi.b #'''',(a0) bne qt4 addq.l #1,a0 move.b #'''',d0 if so, do same as above bra qt1 qt4: bsr ignblk is it an underli  d2. * tstnum: clr.l d1 initialize return parameters clr d2 bsr ignblk skip over blanks tn1: cmp.b #'0',(a0) is it less than zero? bcs tsnmret if so, that's all cmp.b #'9',(a0) is it greater than nine? bhi tsnmret if so, return cmp.l #214748364,d1 see if there's room for new digit bcc qhow if not, we've overflowd move.l d1,d0 quickly multiply result by 10 add.l d1,d1 add.l d1,d1 add.l d0,d1 add.l d1,d1 move.b (a0)+,d0 add in the new digit and.l #$f,d0 add.l d0,d1 addq #1,d2 increment the no. of digits bra tn1 tsnmret: rts * * ===== skip over blanks in the text pointed to by a0. * ignblk: cmp.b #' ',(a0) see if it's a space bne igbret if so, swallow it igb1: addq.l #1,a0 increment the text pointer bra ignblk igbret: rts * * ===== convert the line of text in the input buffer to upper * case (except for stuff between quotes). * toupbuf: lea buffer,a0 set up text pointer clr.b d1 clear quote flag toupb1: move.b (a0)+,d0 get the next text char. d0,d1 moveq #4,d0 trap #3 movem.l (a7)+,d0-d1/a0 rts * * ===== input a character from the console into register d0 (or * return zero status if there's no character available). * *inchr btst #0,$10040 is character ready? * beq incret if not, return zero status * move.b $10042,d0 else get the character * and.b #$7f,d0 zero out the high bit *incret rts inchr: move.l a0,-(a7) moveq #2,d0 trap #3 tst d0 beq.b incret moveq #3,d0 trap #3 incret: move.l (a7)+,a0 rts * * ===== output character to the host (port 2) from register d0 * (preserves all registers.) * auxout: btst #1,$10041 is port 2 ready for a character? beq auxout if not, wait for it move.b d0,$10043 out it goes. rts * * ===== input a character from the host into register d0 (or * return zero status if there's no character available). * auxin: btst #0,$10041 is character ready? beq axiret if not, return zero status move.b $10043,d0 else get the character and.b #$7f,d0 zero out the high ` ``T` ` ` ` ` & .yM @a # 9# l# B# # # .yM ea f<>axa (HA a a JAgldJYYa*Ifa $M&y a # g&y ,K 9 c# "N$Ma"H$M&La`rLISLOANERUSAVNEXLEIGOTGOSURETURREFOINPUPRINPOKSTOBYCALPEERNABSIZTSTE><<.Tj|Hxzb* BRRX^jdrC Exa Z&HBf K`$<.g<g X KBJj`tJjG&RNa># a0`a( y# J gB"Ha$e# ITa ,CE`haa"af2`avaaea4ag <faga`x a0:a`a$ a`ra# a,8`a<`a,aT`a`?a 8"aX`a8`Zaa/"aHf/9 /9 B # `a"9 g.A# # _aL`aja# CeE`\a# ChE`Bah`p# # cmp.b #cr,d0 is it end of line? beq toupbrt if so, return cmp.b #'"',d0 a double quote? beq doquo cmp.b #'''',d0 or a single quote? beq doquo tst.b d1 inside quotes? bne toupb1 if so, do the next one bsr toupper convert to upper case move.b d0,-(a0) store it addq.l #1,a0 bra toupb1 and go back for more toupbrt: rts doquo: tst.b d1 are we inside quotes? bne doquo1 move.b d0,d1 if not, toggle inside-quotes flag bra toupb1 doquo1: cmp.b d0,d1 make sure we're ending proper quote bne toupb1 if not, ignore it clr.b d1 else clear quote flag bra toupb1 * * ===== convert the character in d0 to upper case * toupper: cmp.b #'a',d0 is it < 'a'? bcs toupret cmp.b #'z',d0 or > 'z'? bhi toupret sub.b #32,d0 if not, make it upper case toupret: rts * * 'chkio' checks the input. if there's no input, it will return * to the caller with the z flag set. if there is input, the z * flag is cleared and the input byte is in d0. however, if a * control-c is bit axiret: rts * * ===== return to the resident monitor, operating system, etc. * *byebye move.b #228,d7 return to tutor * trap #14 byebye: clr d0 trap #2 initmsg: .dc.b esc,"EGordo's MC68000 Tiny Basic, v1.0",cr,lf,lf,0 okmsg: .dc.b cr,lf,'ok',cr,lf,0 howmsg: .dc.b 'how?',cr,lf,0 whtmsg: .dc.b 'what?',cr,lf,0 srymsg: .dc.b 'sorry.' clmsg: .dc.b cr,lf,0 .even lstrom = * end of possible rom area * * internal variables follow: * basepag: .ds.l 1 cp/m-68k base-page addr ranpnt: .dc.l start random number pointer currnt: .ds.l 1 current line pointer stkgos: .ds.l 1 saves stack pointer in 'gosub' stkinp: .ds.l 1 saves stack pointer during 'input' lopvar: .ds.l 1 'for' loop save area lopinc: .ds.l 1 increment loplmt: .ds.l 1 limit lopln: .ds.l 1 line number loppt: .ds.l 1 text pointer txtunf: .ds.l 1 points to unfilled text area varbgn: .ds.l 1 points to variable area stklmt: .ds.l 1 holds lower limit for stack growth buffer: .ds.b buflen keyboard input buffer   # ,O` g f$O"NGa.K`$ae|"@ 9 gpga` й i""9 J jAm#  y `ap`` aJf"HBa>d`.y # X _/a` a~eV$@`/are$@B"_al//9 # # / <:aA aB$_$# _Xa,``*  g a@a,`` y< aag<@g<:fa aag< f`# `tBAag<ae_< QNu y"y < aj< abc<:aVa6a2< gaB`<@a8< a0< a(<a `ht<<0<9c^aQNua*a , /a "_``xaJg/"@N _`aV/CmE`a2m$`&a,g` a&o`a n`af `Nual`NuBNupNu Nu "//a"Nua-B`"a+a"ax+/a"Ёi8`ad-g/aD`a&aT* /a"a`aB/E/a "Aa`CVE`a*e"@B Nua* JBfa( aa)Nu`ta@B<@eBf(RHaЀeЀe/a"c 9 Nu< <eRH@@"9 ANu(JjDJjDc AbN4H@H@J@f>Ђk8JjDNuJg*$(JjDJjDv"Bҁрread, 'chkio' will warm-start basic and will not * return to the caller. * chkio: bsr goin get input if possible beq chkret if zero, no input cmp.b #ctrlc,d0 is it control-c? bne chkret if not bra wstart if so, do a warm start chkret: rts * * ===== display a cr-lf sequence * crlf: lea clmsg,a6 * * ===== display a zero-ended string pointed to by register a6 * prmesg: move.b (a6)+,d0 get the char. beq prmret if it's zero, we're done bsr goout else display it bra prmesg prmret: rts ****************************************************** * the following routines are the only ones that need * * to be changed for a different i/o environment. * ****************************************************** * * ===== output character to the console (port 1) from register d0 * (preserves all registers.) * *outchr btst #1,$10040 is port 1 ready for a character? * beq outchr if not, wait for it * move.b d0,$10042 out it goes. * rts outchr: movem.l d0-d1/a0,-(a7) exg  .even txt = * beginning of program area .end  lower limit for stack growth buffer: .ds.b buflen keyboard input buffer !gkRQAJjDDNua"@BNua Jgk""y  eC # a RNuaJjDkNu 9  Nuae:/a= a,_,Nu`&a:X`a X`Nua  fNu/M sa6 _ 9 ggB"y a:<?a,B@SaZ`t/M {`/M l`a< aA ag<g&<gD< g< eaְ< g^ e<a< a c<aS`" gSA<a< a<aQA `z< ajNudJ"y$y Se JSAeNuT  f`ܷg`Nug!`,_# g# # # # N"9 d,_"9 g/9 /9 /9 /9 /Nga< f< aNua"<""Ha I"_< g TNa'<'`a_ < ax"_`Nu&?<JjDSD i ¼`0BAHA 42 HA2HAH@H@SDJfSDk < a QJj<-ak <0a`8NuBIxa< aB@`aL"_gBNRRNBBBa0 0e( 9b" d ҁҁҀҁҀRB`Nu  fR`NuA B< g<"g<'gJfaR`NuJf`ֲfB`ΰ<ae <zb< Nua>g <f`NuM gcommercial * * rights are reserved. * ****************************************************************** cr = $0d *ascii equates lf = $0a tab = $09 ctrlc = $03 ctrlh = $08 ctrls = $13 ctrlx = $18 buflen = 80 *length of keyboard input buffer * * standard jump table. you can change these addresses if you are * customizing this interpreter for a different environment. * .text start: bra cstart *cold start entry point gowarm: bra wstart *warm start entry point goout: bra outc *jump to character-out routine goin: bra inc *jump to character-in routine goauxo: bra auxout *jump to auxiliary-out routine goauxi: bra auxin *jump to auxiliary-in routine gobye: bra byebye *jump to monitor, dos, etc. * * modifiable system constants: * txtbgn: .dc.l txt *beginning of program memory endmem: .dc.l $30000 *end of available memory * * the main interpreter starts here: * cstart: move.l endmem,sp *initialize stack pointer lea intmsg,a6 *tell who we are * ******************************************************************* * * *** tables *** direct *** exec *** * * this section of the code tests a string against a table. when * a match is found, control is transferred to the section of * code according to the table. * * at 'exec', a0 should point to the string, a1 should point to * the character table, and a2 should point to the execution * table. at 'direct', a0 should point to the string, a1 and * a2 will be set up to point to tab1 and tab1x1, which are * the tables of all direct and statement commands. * * a '.' in the string will terminate the test and the partial * match will be considered as a match, e.g. 'p.', 'pr.','pri.', * 'prin.', or 'print' will all match 'print'. * * there are two tables: the character table and the execution * table. the character table consists of any number of text items. * each item is a string of characters with the last character's * high bit set to one. the execution table holds a 16-bit * execution a`Nu9gNu9g 9<Nu9AgCNu9Ag 9C<NupNC Gordos MC68000 Tiny Basic, v1.1 ok how? what? sorry.  bsr prmesg move.l txtbgn,txtunf *init. end-of-program pointer move.l endmem,d0 *get address of end of memory sub.l #2048,d0 *reserve 2k for the stack move.l d0,stklmt sub.l #108,d0 *reserve variable area (27 long words) move.l d0,varbgn wstart: clr.l d0 *initialize internal variables move.l d0,lopvar move.l d0,stkgos move.l d0,currnt *current line number pointer = 0 move.l endmem,sp *init s.p. again, just in case lea okmsg,a6 *display "ok" bsr prmesg st3: move.b #'>',d0 *prompt with a '>' and bsr getln *read a line. bsr toupbuf *convert to upper case move.l a0,a4 *save pointer to end of line lea buffer,a0 *point to the beginning of line bsr tstnum *is there a number there? bsr ignblk *skip trailing blanks tst d1 *does line no. exist? (or nonzero?) beq direct *if not, it's a direct statement cmp.l #$ffff,d1 *see if line no. is <= 16 bits bcc qhow *if not, we've overflowed move.b d1,-(a0) *store the binary line no. ror #8,d1 *(kludge to store a woraddresses that correspond to each entry in the * character table. * * the end of the character table is a 0 byte which corresponds * to the default routine in the execution table, which is * executed if none of the other table items are matched. * * character-matching tables: tab1: .dc.b 'LIS',('T'+$80) *direct commands .dc.b 'LOA',('D'+$80) .dc.b 'NE',('W'+$80) .dc.b 'RU',('N'+$80) .dc.b 'SAV',('E'+$80) tab2: .dc.b 'NEX',('T'+$80) *direct / statement .dc.b 'LE',('T'+$80) .dc.b 'I',('F'+$80) .dc.b 'GOT',('O'+$80) .dc.b 'GOSU',('B'+$80) .dc.b 'RETUR',('N'+$80) .dc.b 'RE',('M'+$80) .dc.b 'FO',('R'+$80) .dc.b 'INPU',('T'+$80) .dc.b 'PRIN',('T'+$80) .dc.b 'POK',('E'+$80) .dc.b 'STO',('P'+$80) .dc.b 'BY',('E'+$80) .dc.b 'CAL',('L'+$80) .dc.b 0 tab4: .dc.b 'PEE',('K'+$80) *functions .dc.b 'RN',('D'+$80) .dc.b 'AB',('S'+$80) .dc.b 'SIZ',('E'+$80) .dc.b 0 tab5: .dc.b 'T',('O'+$80) *"to" in "for" .dc.b 0 tab6: .dc.b 'STE',('P'+$80) *"step" in "for" .dc.b ****************************************************************** * * * tiny basic for the motorola mc68000 * * * * derived from palo alto tiny basic as published in the may 1976 * * issue of dr. dobb's journal. adapted to the 68000 by: * * Gordon Brandly * * R.R. 2 * * Fort Sask., Alberta, Canada * * T8L 2N8 * * * * Version 1.0 as of july 17, 1984 * * * * * ************************* UPDATES ******************************** * This version is for for cp/m-68k with compupro interfacer 1 * * To assemble: as68 -l tbi68k.s [long addresses] * To link: lo68 -taddress -s -o tbi68k.68k tbi68k.o * Revisions: * 03/22/85 rev 1.1 * Change address modes to long word rev 1.1 * Correct error in multiply routine rev 1.1 * * ****************************************************************** * copyright (c) 1984 by Gordon Brandly. this program may be * * freely distributed for personal use only. all d on a move.b d1,-(a0) *possible byte boundary) rol #8,d1 bsr fndln *find this line in save area move.l a1,a5 *save possible line pointer bne st4 *if not found, insert bsr fndnxt *find the next line (into a1) move.l a5,a2 *pointer to line to be deleted move.l txtunf,a3 *points to top of save area bsr mvup *move up to delete move.l a2,txtunf *update the end pointer st4: move.l a4,d0 *calculate the length of new line sub.l a0,d0 cmp.l #3,d0 *is it just a line no. & cr? beq st3 *if so, it was just a delete move.l txtunf,a3 *compute new end move.l a3,a6 add.l d0,a3 move.l varbgn,d0 *see if there's enough room cmp.l a3,d0 bls qsorry *if not, say so move.l a3,txtunf *if so, store new end position move.l a6,a1 *points to old unfilled area move.l a5,a2 *points to beginning of move area bsr mvdown *move things out of the way move.l a0,a1 *set up to do the insertion move.l a5,a2 move.l a4,a3 bsr mvup *do it bra st3 *go back and get another line *" 0 tab8: .dc.b '>',('='+$80) *relational operators .dc.b '<',('>'+$80) .dc.b ('>'+$80) .dc.b ('='+$80) .dc.b '<',('='+$80) .dc.b ('<'+$80) .dc.b 0 .even *<- for aligning on a word boundary * execution address tables: ******** modified to long word rev 1.1 tab1x1: .dc.l list *direct commands .dc.l load .dc.l new .dc.l run .dc.l save tab2x1: .dc.l next *direct / statement .dc.l let .dc.l if .dc.l goto .dc.l gosub .dc.l return .dc.l rem .dc.l for .dc.l input .dc.l print .dc.l poke .dc.l stop .dc.l gobye .dc.l call .dc.l deflt tab4x1: .dc.l peek *functions .dc.l rnd .dc.l abs .dc.l size .dc.l xp40 tab5x1: .dc.l fr1 *"to" in "for" .dc.l qwhat tab6x1: .dc.l fr2 *"step" in "for" .dc.l fr3 tab8x1: .dc.l xp11 >= *relational operators .dc.l xp12 <> .dc.l xp13 > .dc.l xp15 = .dc.l xp14 <= .dc.l xp16 < .dc.l xp17 * direct: lea tab1,a1 lea tab1x1,a2 exec: bsr ignblk *ignore leading blanks move.l a0,a3 *save the 3 more entries in 'run': * 'runnxl' finds next line, stores it's address and executes it. * 'runtsl' stores the address of this line and executes it. * 'runsml' continues the execution on same line. * * 'goto expr' evaluates the expression, finds the target * line, and jumps to 'runtsl' to do it. * new: bsr endchk move.l txtbgn,txtunf *set the end pointer * stop: bsr endchk bra wstart run: bsr endchk move.l txtbgn,a0 *set pointer to beginning move.l a0,currnt runnxl: tst.l currnt executing a program? beq wstart if not, we've finished a direct stat. clr.l d1 else find the next line number move.l a0,a1 bsr fndlnp bcs wstart if we've fallen off the end, stop runtsl: move.l a1,currnt set currnt to point to the line no. move.l a1,a0 set the text pointer to addq.l #2,a0 the start of the line text runsml: bsr chkio see if a control-c was pressed lea tab2,a1 find command in tab2 lea tab2x1,a2 bra exec and execute it goto: bsr expr evaluate the followiint width bra pr3 look for more to print pr1: bsr qtstg is it a string? bra pr8 if not, must be an expression pr3: bsr tstc if ",", go find next pr6x: .dc.b ',',pr6-pr6x-1 bsr fin in the list. bra pr0 pr6: bsr crlf list ends here bra finish pr8: move d4,-(sp) save the width value bsr expr evaluate the expression move (sp)+,d4 restore the width move.l d0,d1 bsr prtnum print its value bra pr3 more to print? finish: bsr fin check end of command bra qwhat print "what?" if wrong * ******************************************************************* * * *** gosub *** & return *** * * 'gosub expr:' or 'gosub expr' is like the 'goto' command, * except that the current text pointer, stack pointer, etc. are * saved so that execution can be continued after the subroutine * 'return's. in order that 'gosub' can be nested (and even * recursive), the save area must be stacked. the stack pointer * is saved in 'stkgos'. the old 'stkgos' is saved on the stack. * if we pointer clr.b d2 *clear match flag exlp: move.b (a0)+,d0 *get the program character move.b (a1),d1 *get the table character bne exngo *if end of table, move.l a3,a0 *restore the text pointer and... bra exgo *execute the default. exngo: move.b d0,d3 *else check for period... and.b d2,d3 *and a match. cmp.b #'.',d3 beq exgo *if so, execute and.b #$7f,d1 *ignore the table's high bit cmp.b d0,d1 *is there a match? beq exmat addq.l #4,a2 *if not, try the next entry rev 1.1 move.l a3,a0 *reset the program pointer clr.b d2 *sorry, no match ex1: tst.b (a1)+ *get to the end of the entry bpl ex1 bra exlp *back for more matching exmat: moveq #-1,d2 *we've got a match so far tst.b (a1)+ *end of table entry? bpl exlp *if not, go back for more exgo: lea 0,a3 *execute the appropriate routine move.l (a2),a3 rev 1.1 jmp (a3) * ******************************************************************* * * what follows is the code to execute direct and statemng expression bsr endchk must find end of line move.l d0,d1 bsr fndln find the target line bne qhow no such line no. bra runtsl go do it * ******************************************************************* * * *** list *** print *** * * list has two forms: * 'list' lists all saved lines * 'list #' starts listing at the line # * control-s pauses the listing, control-c stops it. * * print command is 'print ....:' or 'print ....' * where '....' is a list of expressions, formats, back-arrows, * and strings. these items a separated by commas. * * a format is a pound sign followed by a number. it controls * the number of spaces the value of an expression is going to * be printed in. it stays effective for the rest of the print * command unless changed by another format. if no format is * specified, 11 positions will be used. * * a string is quoted in a pair of single- or double-quotes. * * an underline (back-arrow) means generate a without a * * a e are in the main routine, 'stkgos' is zero (this was done * in the initialization section of the interpreter), but we still * save it as a flag for no further 'return's. * * 'return' undoes everything that 'gosub' did, and thus * returns the execution to the command after the most recent * 'gosub'. if 'stkgos' is zero, it indicates that we never had * a 'gosub' and is thus an error. * gosub: bsr pusha save the current 'for' parameters bsr expr get line number move.l a0,-(sp) save text pointer move.l d0,d1 bsr fndln find the target line bne ahow if not there, say "how?" move.l currnt,-(sp) found it, save old 'currnt'... move.l stkgos,-(sp) and 'stkgos' clr.l lopvar load new values move.l sp,stkgos bra runtsl return: bsr endchk there should be just a move.l stkgos,d1 get old stack pointer beq qwhat if zero, it doesn't exist move.l d1,sp else restore it move.l (sp)+,stkgos and the old 'stkgos' move.l (sp)+,currnt and the old 'currnt' move.l (sp)+,a0 ent * commands. control is transferred to these points via the command * table lookup code of 'direct' and 'exec' in the last section. * after the command is executed, control is transferred to other * sections as follows: * * for 'list', 'new', and 'stop': go back to the warm start point. * for 'run': go execute the first stored line if any* else go * back to the warm start point. * for 'goto' and 'gosub': go execute the target line. * for 'return' and 'next'* go back to saved return line. * for all others: if 'currnt' is 0, go to warm start* else go * execute next command. (this is done in 'finish'.) * ******************************************************************* * * *** new *** stop *** run (& friends) *** goto *** * * 'new' sets txtunf to point to txtbgn * * 'stop' goes back to wstart * * 'run' finds the first stored line, stores its address * in currnt, and starts executing it. note that only those * commands in tab2 are legal for a stored program. * * there ar is generated after the entire list has been printed * or if the list is empty. if the list ends with a semicolon, * however, no is generated. * list: bsr tstnum see if there's a line no. bsr endchk if not, we get a zero bsr fndln find this or next line ls1: bcs wstart warm start if we passed the end bsr prtln print the line bsr chkio check for listing halt request beq ls3 cmp.b #ctrls,d0 pause the listing? bne ls3 ls2: bsr chkio if so, wait for another keypress beq ls2 ls3: bsr fndlnp find the next line bra ls1 print: move #11,d4 d4 = number of print spaces bsr tstc if null list and ":" pr2x: .dc.b ':',pr2-pr2x-1 bsr crlf give cr-lf and continue bra runsml execution on the same line pr2: bsr tstc if null list and pr0x: .dc.b cr,pr0-pr0x-1 bsr crlf also give cr-lf and bra runnxl execute the next line pr0: bsr tstc else is it a format? pr1x: .dc.b '#',pr1-pr1x-1 bsr expr yes, evaluate expression move d0,d4 and save it as pr#and the old text pointer bsr popa and the old 'for' parameters bra finish and we are back home * ******************************************************************* * * *** for *** & next *** * * 'for' has two forms: * 'for var=exp1 to exp2 step exp1' and 'for var=exp1 to exp2' * the second form means the same thing as the first form with a * step of positive 1. the interpreter will find the variable 'var' * and set its value to the current value of 'exp1'. it also * evaluates 'exp2' and 'exp1' and saves all these together with * the text pointer, etc. in the 'for' save area, which consisits of * 'lopvar', 'lopinc', 'loplmt', 'lopln', and 'loppt'. if there is * already something in the save area (indicated by a non-zero * 'lopvar'), then the old save area is saved on the stack before * the new values are stored. the interpreter will then dig in the * stack and find out if this same variable was used in another * currently active 'for' loop. if that is the case, then the old * 'add in loop increment bvs qhow say "how?" for 32-bit overflow move.l d0,(a1) save control variable's new value move.l loplmt,d1 get loop's limit value tst.l lopinc bpl nx1 branch if loop increment is positive exg d0,d1 nx1: cmp.l d0,d1 test against limit blt nx2 branch if outside limit move.l lopln,currnt within limit, go back to the... move.l loppt,a0 saved 'currnt' and text pointer. bra finish nx2: bsr popa purge this loop bra finish * ******************************************************************* * * *** rem *** if *** input *** let (& deflt) *** * * 'rem' can be followed by anything and is ignored by the * interpreter. * * 'if' is followed by an expression, as a condition and one or * more commands (including other 'if's) separated by colons. * note that the word 'then' is not used. the interpreter evaluates * the expression. if it is non-zero, execution continues. if it * is zero, the commands that follow are ignored and execution * continues on the n "what?" it isn't? move.l d0,a2 put away the variable's address move.b (a0),d2 get ready for 'prtstg' clr.b d0 move.b d0,(a0) move.l (sp)+,a1 bsr prtstg print string as prompt move.b d2,(a0) restore text ip3: move.l a0,-(sp) save in case of error move.l currnt,-(sp) also save 'currnt' move.l #-1,currnt flag that we are in input move.l sp,stkinp save the stack pointer too move.l a2,-(sp) save the variable address move.b #':',d0 print a colon first bsr getln then get an input line lea buffer,a0 point to the buffer bsr expr evaluate the input move.l (sp)+,a2 restore the variable address move.l d0,(a2) save value in variable move.l (sp)+,currnt restore old 'currnt' move.l (sp)+,a0 and the old text pointer ip4: addq.l #4,sp clean up the stack bsr tstc is the next thing a comma? ip5x: .dc.b ',',ip5-ip5x-1 bra input yes, more items ip5: bra finish deflt: cmp.b #cr,(a0) empty line is ok beq lt1 else it is 'let' let: bsr setval do the assignment bsrfor' loop is deactivated. (i.e. purged from the stack) * * 'next var' serves as the logical (not necessarily physical) end * of the 'for' loop. the control variable 'var' is checked with * the 'lopvar'. if they are not the same, the interpreter digs in * the stack to find the right one and purges all those that didn't * match. either way, it then adds the 'step' to that variable and * checks the result with against the limit value. if it is within * the limit, control loops back to the command following the * 'for'. if it's outside the limit, the save area is purged and * execution continues. * for: bsr pusha save the old 'for' save area bsr setval set the control variable move.l a6,lopvar save its address lea tab5,a1 use 'exec' to test for 'to' lea tab5x1,a2 bra exec fr1: bsr expr evaluate the limit move.l d0,loplmt save that lea tab6,a1 use 'exec' to look for the lea tab6x1,a2 word 'step' bra exec fr2: bsr expr found it, get the step value bra fr4 fr3: moveq #1,ext line. * * 'input' is like the 'print' command, and is followed by a list * of items. if the item is a string in single or double quotes, * or is an underline (back arrow), it has the same effect as in * 'print'. if an item is a variable, this variable name is * printed out followed by a colon, then the interpreter waits for * an expression to be typed in. the variable is then set to the * value of this expression. if the variable is preceeded by a * string (again in single or double quotes), the string will be * displayed followed by a colon. the interpreter the waits for an * expression to be entered and sets the variable equal to the * expression's value. if the input expression is invalid, the * interpreter will print "what?", "how?", or "sorry" and reprint * the prompt and redo the input. the execution will not terminate * unless you press control-c. this is handled in 'inperr'. * * 'let' is followed by a list of items separated by commas. * each item consists of a variable,  tstc check for more 'let' items lt1x: .dc.b ',',lt1-lt1x-1 bra let lt1: bra finish until we are finished. * ******************************************************************* * * *** load *** & save *** * * these two commands transfer a program to/from an auxiliary * device such as a cassette, another computer, etc. the program * is converted to an easily-stored format: each line starts with * a colon, the line no. as 4 hex digits, and the rest of the line. * at the end, a line starting with an '@' sign is sent. this * format can be read back with a minimum of processing time by * the 68000. * load: move.l txtbgn,a0 set pointer to start of prog. area move.b #cr,d0 for a cp/m host, tell it we're ready... bsr goauxo by sending a cr to finish pip command. lod1: bsr goauxi look for start of line beq lod1 cmp.b #'@',d0 end of program? beq lodend cmp.b #':',d0 if not, is it start of line? bne lod1 if not, wait for it bsr gbyte get first byte of line no. move.b d1,d0 not found, step defaults to 1 fr4: move.l d0,lopinc save that too fr5: move.l currnt,lopln save address of current line number move.l a0,loppt and text pointer move.l sp,a6 dig into the stack to find 'lopvar' bra fr7 fr6: add.l #20,a6 look at next stack frame fr7: move.l (a6),d0 is it zero? beq fr8 if so, we're done cmp.l lopvar,d0 same as current lopvar? bne fr6 nope, look some more move.l sp,a2 else remove 5 long words from... move.l a6,a1 inside the stack. lea 20,a3 add.l a1,a3 bsr mvdown move.l a3,sp set the sp 5 long words up fr8: bra finish and continue execution next: bsr tstv get address of variable bcs qwhat if no variable, say "what?" move.l d0,a1 save variable's address nx0: move.l lopvar,d0 if 'lopvar' is zero, we never... beq qwhat had a for loop, so say "what?" cmp.l d0,a1 else we check them beq nx3 ok, they agree bsr popa nope, let's see the next frame bra nx0 nx3: move.l (a1),d0 get control variable's value add.l lopinc,d0 an equals sign, and an * expression. the interpreter evaluates the expression and sets * the variable to that value. the interpreter will also handle * 'let' commands without the word 'let'. this is done by 'deflt'. * rem: bra if2 skip the rest of the line if: bsr expr evaluate the expression if1: tst.l d0 is it zero? bne runsml if not, continue if2: move.l a0,a1 clr.l d1 bsr fndskp if so, skip the rest of the line bcc runtsl and run the next line bra wstart if no next line, do a warm start inperr: move.l stkinp,sp restore the old stack pointer move.l (sp)+,currnt and old 'currnt' addq.l #4,sp move.l (sp)+,a0 and old text pointer input: move.l a0,-(sp) save in case of error bsr qtstg is next item a string? bra ip2 nope bsr tstv yes, but is it followed by a variable? bcs ip4 if not, branch move.l d0,a2 put away the variable's address bra ip3 if so, input to variable ip2: move.l a0,-(sp) save for 'prtstg' bsr tstv must be a variable now bcs qwhat$(a0)+ store it bsr gbyte get 2nd bye of line no. move.b d1,(a0)+ store that, too lod2: bsr goauxi get another text char. beq lod2 move.b d0,(a0)+ store it cmp.b #cr,d0 is it the end of the line? bne lod2 if not, go back for more bra lod1 if so, start a new line lodend: move.l a0,txtunf set end-of program pointer bra wstart back to direct mode gbyte: moveq #1,d2 get two hex characters from auxiliary clr d1 and store them as a byte in d1 gbyte1: bsr goauxi get a char. beq gbyte1 cmp.b #'a',d0 bcs gbyte2 subq.b #7,d0 if greater than 9, adjust gbyte2: and.b #$f,d0 strip ascii lsl.b #4,d1 put nybble into the result or.b d0,d1 dbra d2,gbyte1 get another char. rts save: move.l txtbgn,a0 set pointer to start of prog. area move.l txtunf,a1 set pointer to end of prog. area save1: move.b #cr,d0 send out a cr & lf (cp/m likes this) bsr goauxo move.b #lf,d0 bsr goauxo cmp.l a0,a1 are we finished? bls savend move.b #':',d0 if not, start a line bsr  * * *** expr *** * * 'expr' evaluates arithmetical or logical expressions. * ::= * * where is one of the operators in tab8 and the result * of these operations is 1 if true and 0 if false. * ::=(+ or -)(+ or -)(... * where () are optional and (... are optional repeats. * ::=( <* or /> )(... * ::= * * () * is recursive so that the variable '@' can have an * as an index, functions can have an as arguments, and * can be an in parenthesis. * expr: bsr expr2 move.l d0,-(sp) save value lea tab8,a1 look up a relational operator lea tab8x1,a2 bra exec go do it xp11: bsr xp18 is it ">="? blt xprt0 no, return d0=0 bra xprt1 else return d0=1 xp12: bsr xp18 is it "<>"? beq xprt0 no, return d0=0 bra xprt1 else return d0=1 xp13: bsr xp18 is it ">"? ble xprt0 no, return d0=0 bra xprt1 else move.l d0,a1 clr.l d0 move.l (a1),d0 if a variable, return its value in d0 exp4rt: rts xp41: bsr tstnum or is it a number? move.l d1,d0 tst d2 (if not, # of digits will be zero) bne exp4rt if so, return it in d0 parn: bsr tstc else look for ( expr ) xp43x: .dc.b '(',xp43-xp43x-1 bsr expr bsr tstc xp43xx: .dc.b ')',xp43-xp43xx-1 xp42: rts xp43: bra qwhat else say "what?" * * ===== test for a valid variable name. returns carry=1 if not * found, else returns carry=0 and the address of the * variable in d0. tstv: bsr ignblk clr.l d0 move.b (a0),d0 look at the program text sub.b #'@',d0 bcs tstvrt c=1: not a variable bne tv1 branch if not "@" array addq #1,a0 if it is, it should be bsr parn followed by (expr) as its index. add.l d0,d0 bcs qhow say "how?" if index is too big add.l d0,d0 bcs qhow move.l d0,-(sp) save the index bsr size get amount of free memory move.l (sp)+,d1 get back the index cmp.l d1,d0 see if there's enough memory bls goauxo move.b (a0)+,d1 send first half of line no. bsr pbyte move.b (a0)+,d1 and send 2nd half bsr pbyte save2: move.b (a0)+,d0 get a text char. cmp.b #cr,d0 is it the end of the line? beq save1 if so, send cr & lf and start new line bsr goauxo send it out bra save2 go back for more text savend: move.b #'@',d0 send end-of-program indicator bsr goauxo move.b #cr,d0 followed by a cr & lf bsr goauxo move.b #lf,d0 bsr goauxo move.b #$1a,d0 and a control-z to end the cp/m file bsr goauxo bra wstart then go do a warm start pbyte: moveq #1,d2 send two hex characters from d1's low byte pbyte1: rol.b #4,d1 get the next nybble move.b d1,d0 and.b #$f,d0 strip off garbage add.b #'0',d0 make it into ascii cmp.b #'9',d0 bls pbyte2 addq.b #7,d0 adjust if greater than 9 pbyte2: bsr goauxo send it out dbra d2,pbyte1 then send the next nybble rts * ******************************************************************* * * *** poke *** & call *** * * 'pokreturn d0=1 xp14: bsr xp18 is it "<="? bgt xprt0 no, return d0=0 bra xprt1 else return d0=1 xp15: bsr xp18 is it "="? bne xprt0 if not, return d0=0 bra xprt1 else return d0=1 xp15rt: rts xp16: bsr xp18 is it "<"? bge xprt0 if not, return d0=0 bra xprt1 else return d0=1 xp16rt: rts xprt0: clr.l d0 return d0=0 (false) rts xprt1: moveq #1,d0 return d0=1 (true) rts xp17: move.l (sp)+,d0 it's not a rel. operator rts return d0= xp18: move.l (sp)+,d0 reverse the top two stack items move.l (sp)+,d1 move.l d0,-(sp) move.l d1,-(sp) bsr expr2 do second move.l (sp)+,d1 cmp.l d0,d1 compare with the first result rts return the result expr2: bsr tstc negative sign? xp21x: .dc.b '-',xp21-xp21x-1 clr.l d0 yes, fake '0-' bra xp26 xp21: bsr tstc positive sign? ignore it xp22x: .dc.b '+',xp22-xp22x-1 xp22: bsr expr3 first xp23: bsr tstc add? xp25x: .dc.b '+',xp25-xp25x-1 move.l d0,-(sp) yes, save the value bsr expqsorry if not, say "sorry" move.l varbgn,d0 put address of array element... sub.l d1,d0 into d0 rts tv1: cmp.b #27,d0 if not @, is it a through z? eori.b #1,ccr play with condition code reg bcs tstvrt if not, set carry and return addq #1,a0 else bump the text pointer add d0,d0 compute the variable's address add d0,d0 move.l varbgn,d1 add d1,d0 and return it in d0 with carry=0 tstvrt: rts * * ===== multiplies the 32 bit values in d0 and d1, returning * the 32 bit result in d0. * mult32: move.l d1,d4 eor.l d0,d4 see if the signs are the same tst.l d0 take absolute value of d0 bpl mlt1 neg.l d0 mlt1: tst.l d1 take absolute value of d1 bpl mlt2 neg.l d1 mlt2: cmp.l #$ffff,d1 is second argument <= 16 bits? bls mlt3 ok, let it through exg d0,d1 else swap the two arguments cmp.l #$ffff,d1 and check 2nd argument again bhi qhow one of them must be 16 bits mlt3: move d0,d2 prepare for 32 bit x 16 bit multiply mulu d1,d2 multiply low word swap d0 e expr1,expr2' stores the byte from 'expr2' into the memory * address specified by 'expr1'. * * 'call expr' jumps to the machine language subroutine whose * starting address is specified by 'expr'. the subroutine can use * all registers but must leave the stack the way it found it. * the subroutine returns to the interpreter by executing an rts. * poke: bsr expr get the memory address bsr tstc it must be followed by a comma pkerx: .dc.b ',',pker-pkerx-1 move.l d0,-(sp) save the address bsr expr get the byte to be poke'd move.l (sp)+,a1 get the address back move.b d0,(a1) store the byte in memory bra finish pker: bra qwhat if no comma, say "what?" call: bsr expr get the subroutine's address tst.l d0 make sure we got a valid address beq qhow if not, say "how?" move.l a0,-(sp) save the text pointer move.l d0,a1 jsr (a1) jump to the subroutine move.l (sp)+,a0 restore the text pointer bra finish * *******************************************************************r3 get the second xp24: move.l (sp)+,d1 add.l d1,d0 add it to the first bvs qhow branch if there's an overflow bra xp23 else go back for more operations xp25: bsr tstc subtract? xp42x: .dc.b '-',xp42-xp42x-1 xp26: move.l d0,-(sp) yes, save the result of 1st bsr expr3 get second neg.l d0 change its sign bra xp24 and do an addition expr3: bsr expr4 get first xp31: bsr tstc multiply? xp34x: .dc.b '*',xp34-xp34x-1 move.l d0,-(sp) yes, save that first result bsr expr4 get second move.l (sp)+,d1 bsr mult32 multiply the two bra xp31 then look for more terms xp34: bsr tstc divide? xp42xx: .dc.b '/',xp42-xp42xx-1 move.l d0,-(sp) save result of 1st bsr expr4 get second move.l (sp)+,d1 exg d0,d1 bsr div32 do the division bra xp31 go back for any more terms expr4: lea tab4,a1 find possible function lea tab4x1,a2 bra exec xp40: bsr tstv nope, not a function bcs xp41 nor a variable %mulu d1,d0 multiply high word swap d0 ******** correction for overflow *********** * if lower word is not zero then was an overflow tst d0 rev 1.1 bne qhow if overflow on multiply, say "how" rev 1.1 add.l d2,d0 d0 now holds the product * if sign bit set after add then overflow bmi qhow if overflow, say "how?" rev 1.1 ********************************************* tst.l d4 were the signs the same? bpl mltret neg.l d0 if not, make the result negative mltret: rts * * ===== divide the 32 bit value in d0 by the 32 bit value in d1. * returns the 32 bit quotient in d0, remainder in d1. * div32: tst.l d1 check for divide-by-zero beq qhow if so, say "how?" move.l d1,d2 move.l d1,d4 eor.l d0,d4 see if the signs are the same tst.l d0 take absolute value of d0 bpl div1 neg.l d0 div1: tst.l d1 take absolute value of d1 bpl div2 neg.l d1 div2: moveq #31,d3 iteration count for 32 bits move.l d0,d1 clr.l d0 div3: add.l d1,d1 (this algorithm was translaended with a cr, it finds the * the next line and continues from there. * * 'endchk' checks if a command is ended with a cr. this is * required in certain commands, such as goto, return, stop, etc. * * 'error' prints the string pointed to by a0. it then prints the * line pointed to by currnt with a "?" inserted at where the * old text pointer (should be on top of the stack) points to. * execution of tiny basic is stopped and a warm start is done. * if currnt is zero (indicating a direct command), the direct * command is not printed. if currnt is -1 (indicating * 'input' command in progress), the input line is not printed * and execution is not terminated but continues at 'inperr'. * * related to 'error' are the following: * 'qwhat' saves text pointer on stack and gets "what?" message. * 'awhat' just gets the "what?" message and jumps to 'error'. * 'qsorry' and 'asorry' do the same kind of thing. * 'qhow' and 'ahow' also do this for "how?". * setval: bsr tstv variable name? bcs qwhat igetln' to return. * * 'fndln' finds a line with a given line no. (in d1) in the * text save area. a1 is used as the text pointer. if the line * is found, a1 will point to the beginning of that line * (i.e. the high byte of the line no.), and flags are nc & z. * if that line is not there and a line with a higher line no. * is found, a1 points there and flags are nc & nz. if we reached * the end of the text save area and cannot find the line, flags * are c & nz. * 'fndln' will initialize a1 to the beginning of the text save * area to start the search. some other entries of this routine * will not initialize a1 and do the search. * 'fndlnp' will start with a1 and search for the line no. * 'fndnxt' will bump a1 by 2, find a cr and then start search. * 'fndskp' uses a1 to find a cr, and then starts the search. * getln: bsr goout display the prompt move.b #' ',d0 and a space bsr goout lea buffer,a0 a0 is the buffer pointer gl1: bsr chkio check keyboard beq gl1 wait for a char. to cometed from addx.l d0,d0 the divide routine in ron cain's beq div4 small-c run time library.) cmp.l d2,d0 bmi div4 addq.l #1,d1 sub.l d2,d0 div4: dbra d3,div3 exg d0,d1 put rem. & quot. in proper registers tst.l d4 were the signs the same? bpl divrt neg.l d0 if not, results are negative neg.l d1 divrt: rts * * ===== the peek function returns the byte stored at the address * contained in the following expression. * peek: bsr parn get the memory address move.l d0,a1 clr.l d0 upper 3 bytes will be zero move.b (a1),d0 get the addressed byte rts and return it * * ===== the rnd function returns a random number from 1 to * the value of the following expression in d0. * rnd: bsr parn get the upper limit tst.l d0 it must be positive and non-zero beq qhow bmi qhow move.l d0,d1 move.l ranpnt,a1 get memory as a random number cmp.l #lstrom,a1 bcs ra1 lea start,a1 wrap around if end of program ra1: move.l (a1)+,d0 get the slightly random number bclr f not, say "what?" move.l d0,-(sp) save the variable's address bsr tstc get past the "=" sign svlx: .dc.b '=',sv1-svlx-1 bsr expr evaluate the expression move.l (sp)+,a6 move.l d0,(a6) and save its value in the variable rts sv1: bra qwhat if no "=" sign fin: bsr tstc *** fin *** fi1x: .dc.b ':',fi1-fi1x-1 addq.l #4,sp if ":", discard return address bra runsml continue on the same line fi1: bsr tstc not ":", is it a cr? fi2x: .dc.b cr,fi2-fi2x-1 addq.l #4,sp yes, purge return address bra runnxl execute the next line fi2: rts else return to the caller endchk: bsr ignblk cmp.b #cr,(a0) does it end with a cr? bne qwhat if not, say "what?" rts qwhat: move.l a0,-(sp) awhat: lea whtmsg,a6 error: bsr prmesg display the error message move.l (sp)+,a0 restore the text pointer move.l currnt,d0 get the current line number beq wstart if zero, do a warm start cmp.l #-1,d0 is the line no. pointer = -1? beq inperr if so, redo input move.b (a0),-(sp) save  in cmp.b #ctrlh,d0 delete last character? beq gl3 if so cmp.b #ctrlx,d0 delete the whole line? beq gl4 if so cmp.b #cr,d0 accept a cr beq gl2 cmp.b #' ',d0 if other control char., discard it bcs gl1 gl2: move.b d0,(a0)+ save the char. bsr goout echo the char back out cmp.b #cr,d0 if it's a cr, end the line beq gl7 cmp.l #(buffer+buflen-1),a0 any more room? bcs gl1 yes: get some more, else delete last char. gl3: move.b #ctrlh,d0 delete a char. if possible bsr goout move.b #' ',d0 bsr goout cmp.l #buffer,a0 any char.'s left? bls gl1 if not move.b #ctrlh,d0 if so, finish the bs-space-bs sequence bsr goout subq.l #1,a0 decrement the text pointer bra gl1 back for more gl4: move.l a0,d1 delete the whole line sub.l #buffer,d1 figure out how many backspaces we need beq gl6 if none needed, branch subq #1,d1 adjust for dbra gl5: move.b #ctrlh,d0 and display bs-space-bs sequences bsr goout move.b #' ',d0 bsr goout move.b #ctrlh,d0 bsr goout #31,d0 make sure it's positive move.l a1,ranpnt (even i can do better than this!) bsr div32 rnd(n)=mod(number,n)+1 move.l d1,d0 mod is the remainder of the div. addq.l #1,d0 rts * * ===== the abs function returns an absolute value in d0. * abs: bsr parn get the following expr.'s value tst.l d0 bpl absrt neg.l d0 if negative, complement it bmi qhow if still negative, it was too big absrt: rts * * ===== the size function returns the size of free memory in d0. * size: move.l varbgn,d0 get the number of free bytes... sub.l txtunf,d0 between 'txtunf' and 'varbgn' rts return the number in d0 * ******************************************************************* * * *** setval *** fin *** endchk *** error (& friends) *** * * 'setval' expects a variable, followed by an equal sign and then * an expression. it evaluates the expression and sets the variable * to that value. * * 'fin' checks the end of a command. if it ended with ":", * execution continues. if it the char. pointed to clr.b (a0) put a zero where the error is move.l currnt,a1 point to start of current line bsr prtln display the line in error up to the 0 move.b (sp)+,(a0) restore the character move.b #'?',d0 display a "?" bsr goout clr d0 subq.l #1,a1 point back to the error char. bsr prtstg display the rest of the line bra wstart and do a warm start qsorry: move.l a0,-(sp) asorry: lea srymsg,a6 bra error qhow: move.l a0,-(sp) error: "how?" ahow: lea howmsg,a6 bra error * ******************************************************************* * * *** getln *** fndln (& friends) *** * * 'getln' reads in input line into 'buffer'. it first prompts with * the character in d0 (given by the caller), then it fills the * buffer and echos. it ignores lf's but still echos * them back. control-h is used to delete the last character * entered (if there is one), and control-x is used to delete the * whole line and start over again. cr signals the end of a line, * and causes '& dbra d1,gl5 gl6: lea buffer,a0 reinitialize the text pointer bra gl1 and go back for more gl7: move.b #lf,d0 echo a lf for the cr bsr goout rts fndln: cmp.l #$ffff,d1 line no. must be < 65535 bcc qhow move.l txtbgn,a1 init. the text save pointer fndlnp: move.l txtunf,a2 check if we passed the end subq.l #1,a2 cmp.l a1,a2 rev 1.1 bcs fndret if so, return with z=0 & c=1 move.b (a1)+,d2 if not, get a line no. lsl #8,d2 move.b (a1),d2 subq.l #1,a1 cmp d1,d2 is this the line we want? bcs fndnxt no, not there yet fndret: rts return the cond. codes fndnxt: addq.l #2,a1 find the next line fndskp: cmp.b #cr,(a1)+ try to find a cr bne fndskp keep looking bra fndlnp check if end of text * ******************************************************************* * * *** mvup *** mvdown *** popa *** pusha *** * * 'mvup' moves a block up from where a1 points to where a2 points * until a1=a3 * * 'mvdown' moves a block down from where a1 points to where a3  * 'prtln' prints the saved text line pointed to by a1 * with line no. and all. * prtstg: move.b d0,d1 save the stop character ps1: move.b (a1)+,d0 get a text character cmp.b d0,d1 same as stop character? beq prtret if so, return bsr goout display the char. cmp.b #cr,d0 is it a c.r.? bne ps1 no, go back for more move.b #lf,d0 yes, add a l.f. bsr goout prtret: rts then return qtstg: bsr tstc *** qtstg *** qt3x: .dc.b '"',qt3-qt3x-1 move.b #'"',d0 it is a " qt1: move.l a0,a1 bsr prtstg print until another move.l a1,a0 move.l (sp)+,a1 pop return address cmp.b #lf,d0 was last one a cr? beq runnxl if so, run next line qt2: addq.l #2,a1 skip 2 bytes on return jmp (a1) return qt3: bsr tstc is it a single quote? qt4x: .dc.b '''',qt4-qt4x-1 move.b #'''',d0 if so, do same as above bra qt1 qt4: bsr tstc is it an underline? qt5x: .dc.b '_',qt5-qt5x-1 move.b #cr,d0 if so, output a cr without lf bsr goout move.l (sp)+,a1 pop return address bra qt2 q,a1 get the return address move.b (a1)+,d1 get the byte to compare cmp.b (a0),d1 is it = to what a0 points to? beq tc1 if so clr.l d1 if not, add the second move.b (a1),d1 byte following the call to add.l d1,a1 the return address. jmp (a1) jump to the routine tc1: addq.l #1,a0 if equal, bump text pointer addq.l #1,a1 skip the 2 bytes following jmp (a1) the call and continue. * * ===== see if the text pointed to by a0 is a number. if so, * return the number in d1 and the number of digits in d2, * else return zero in d1 and d2. * tstnum: clr.l d1 initialize return parameters clr d2 bsr ignblk skip over blanks tn1: cmp.b #'0',(a0) is it less than zero? bcs tsnmret if so, that's all cmp.b #'9',(a0) is it greater than nine? bhi tsnmret if so, return cmp.l #214748364,d1 see if there's room for new digit bcc qhow if not, we've overflowd move.l d1,d0 quickly multiply result by 10 add.l d1,d1 add.l d1,d1 add.l d0,d1 add.l d1,d1 move.b (a0)+,d0 add in * points until a1=a2 * * 'popa' restores the 'for' loop variable save area from the stack * * 'pusha' stacks for 'for' loop variable save area onto the stack * mvup: cmp.l a1,a3 see the above description beq mvret move.b (a1)+,(a2)+ bra mvup mvret: rts mvdown: cmp.l a1,a2 see the above description beq mvret move.b -(a1),-(a3) bra mvdown popa: move.l (sp)+,a6 a6 = return address move.l (sp)+,lopvar restore lopvar, but zero means no more beq pp1 move.l (sp)+,lopinc if not zero, restore the rest move.l (sp)+,loplmt move.l (sp)+,lopln move.l (sp)+,loppt pp1: jmp (a6) return pusha: move.l stklmt,d1 are we running out of stack room? sub.l sp,d1 bcc qsorry if so, say we're sorry move.l (sp)+,a6 else get the return address move.l lopvar,d1 save loop variables beq pu1 if lopvar is zero, that's all move.l loppt,-(sp) else save all the others move.l lopln,-(sp) move.l loplmt,-(sp) move.l lopinc,-(sp) pu1: move.l d1,-(sp) jmp (a6) return * *********t5: rts none of the above prtnum: move.l d1,d3 save the number for later move d4,-(sp) save the width value move.b #$ff,-(sp) flag for end of digit string tst.l d1 is it negative? bpl pn1 if not neg.l d1 else make it positive subq #1,d4 one less for width count pn1: divu #10,d1 get the next digit bvs pnov overflow flag set? move.l d1,d0 if not, save remainder and.l #$ffff,d1 strip the remainder bra toascii skip the overflow stuff pnov: move d1,d0 prepare for long word division clr.w d1 zero out low word swap d1 high word into low divu #10,d1 divide high word move d1,d2 save quotient move d0,d1 low word into low divu #10,d1 divide low word move.l d1,d0 d0 = remainder swap d1 r/q becomes q/r move d2,d1 d1 is low/high swap d1 d1 is finally high/low toascii: swap d0 get remainder move.b d0,-(sp) stack it as a digit swap d0 subq #1,d4 decrement width count tst.l d1 if quotient is zero, we're done bne pn1 subq #1,d4 adjust padding c the new digit and.l #$f,d0 add.l d0,d1 addq #1,d2 increment the no. of digits bra tn1 tsnmret: rts * * ===== skip over blanks in the text pointed to by a0. * ignblk: cmp.b #' ',(a0) see if it's a space bne igbret if so, swallow it igb1: addq.l #1,a0 increment the text pointer bra ignblk igbret: rts * * ===== convert the line of text in the input buffer to upper * case (except for stuff between quotes). * toupbuf: lea buffer,a0 set up text pointer clr.b d1 clear quote flag toupb1: move.b (a0)+,d0 get the next text char. cmp.b #cr,d0 is it end of line? beq toupbrt if so, return cmp.b #'"',d0 a double quote? beq doquo cmp.b #'''',d0 or a single quote? beq doquo tst.b d1 inside quotes? bne toupb1 if so, do the next one bsr toupper convert to upper case move.b d0,-(a0) store it addq.l #1,a0 bra toupb1 and go back for more toupbrt: rts doquo: tst.b d1 are we inside quotes? bne doquo1 move.b d0,d1 if not, toggle inside-quotes flag bra tou********************************************************** * * *** prtstg *** qtstg *** prtnum *** prtln *** * * 'prtstg' prints a string pointed to by a1. it stops printing * and returns to the caller when either a cr is printed or when * the next byte is the same as what was passed in d0 by the * caller. * * 'qtstg' looks for an underline (back-arrow on some systems), * single-quote, or double-quote. if none of these are found, returns * to the caller. if underline, outputs a cr without a lf. if single * or double quote, prints the quoted string and demands a matching * end quote. after the printing, the next 2 bytes of the caller are * skipped over (usually a short branch instruction). * * 'prtnum' prints the 32 bit number in d1, leading blanks are added if * needed to pad the number of spaces to the number in d4. * however, if the number of digits is larger than the no. in * d4, all digits are printed anyway. negative sign is also * printed and counted in, positive sign is not. * ount for dbra bmi pn4 skip padding if not needed pn3: move.b #' ',d0 display the required leading spaces bsr goout dbra d4,pn3 pn4: tst.l d3 is number negative? bpl pn5 move.b #'-',d0 if so, display the sign bsr goout pn5: move.b (sp)+,d0 now unstack the digits and display bmi pnret until the flag code is reached add.b #'0',d0 make into ascii bsr goout bra pn5 pnret: move (sp)+,d4 restore width value rts prtln: clr.l d1 move.b (a1)+,d1 get the binary line number lsl #8,d1 move.b (a1)+,d1 moveq #5,d4 display a 5 digit line no. bsr prtnum move.b #' ',d0 followed by a blank bsr goout clr d0 stop char. is a zero bra prtstg display the rest of the line * * ===== test text byte following the call to this subroutine. if it * equals the byte pointed to by a0, return to the code following * the call. if they are not equal, branch to the point * indicated by the offset byte following the text byte. * tstc: bsr ignblk ignore leading blanks move.l (sp)+'pb1 doquo1: cmp.b d0,d1 make sure we're ending proper quote bne toupb1 if not, ignore it clr.b d1 else clear quote flag bra toupb1 * * ===== convert the character in d0 to upper case * toupper: cmp.b #'a',d0 is it < 'a'? bcs toupret cmp.b #'z',d0 or > 'z'? bhi toupret sub.b #32,d0 if not, make it upper case toupret: rts * * 'chkio' checks the input. if there's no input, it will return * to the caller with the z flag set. if there is input, the z * flag is cleared and the input byte is in d0. however, if a * control-c is read, 'chkio' will warm-start basic and will not * return to the caller. * chkio: bsr goin get input if possible beq chkret if zero, no input cmp.b #ctrlc,d0 is it control-c? bne chkret if not bra wstart if so, do a warm start chkret: rts * * ===== display a cr-lf sequence * crlf: lea clmsg,a6 * * ===== display a zero-ended string pointed to by register a6 * prmesg: move.b (a6)+,d0 get the char. beq prmret if it's zero, we're doointer stkgos: .ds.l 1 saves stack pointer in 'gosub' stkinp: .ds.l 1 saves stack pointer during 'input' lopvar: .ds.l 1 'for' loop save area lopinc: .ds.l 1 increment loplmt: .ds.l 1 limit lopln: .ds.l 1 line number loppt: .ds.l 1 text pointer txtunf: .ds.l 1 points to unfilled text area varbgn: .ds.l 1 points to variable area stklmt: .ds.l 1 holds lower limit for stack growth buffer: .ds.b buflen keyboard input buffer txt = * beginning of program area .end DN a2a *fR/a""a`a /fVR/a "Aa`CnE`a6e"@B NuaT JBfa (fRaan )fRNua^B<@eBf(RHaЀeЀe/a"c 9Nu< <eRH@@"9ANu(JjDJjDc Ab^4H@H@J@fNЂkHJjDNuJg:$(JjDJjDv"BҁрgkRQAJjDDNua "@BNuaJgk""yܳeC #a RNuaJjDkNu 9NuaeJ/a$ =f>Raj,_,Nua :fRX`a  fRX`Nua  fNu/MaD _ 9gjgB"ya`<?aB@San`<a6QA `z< a NudJ"y$ySe)Ad T  f`Nu$yS`$yS`g`Nug!`,_#g####N"9d,_"9g/9/9/9/9/Ngab< f< aTNua "fR<""Ha I"_< gTNa 'fRne bsr goout else display it bra prmesg prmret: rts ****************************************************** * the following routines are the only ones that need * * to be changed for a different i/o environment. * ****************************************************** * * ===== output character to the console (port 1) from register d0 * (preserves all registers.) * data1 = $007F0000 *Compupro interfacer status1 = data1+1 dav = 1 *bit to test tbmt = 0 outc: btst #tbmt,status1 *is port 1 ready for a character? beq outc *if not, wait for it move.b d0,data1 *out it goes. rts * * ===== input a character from the console into register d0 (or * return zero status if there's no character available). * inc: btst #dav,status1 *is character ready? beq incret *if not, return zero status move.b data1,d0 *else get the character and.b #$7f,d0 *zero out the high bit incret: rts * * ===== output character to the host (port 2) from register d0 * (preserves all registers.) `\``f` >` J` X` f` x\# o#.hMa # 9#l#B###.yMa <>a a <(HA a a JAgPd YYa $*Ifa P$M&ya X# g&y,K 9c 0#"N$Ma ,"H$M&La `rLISLOANERUSAVNEXLEIGOTGOSURETURREFOINPUPRINPOKCURSOSTOBYCALPEERNABSIZTSTE PDZ 6 < `   R  48D| 0CEa &HBf K`$<.g<g X KBJj`tJj&RNa#a`a y#JgB"H$ySa~e# ITa C0E`fara2"a6f`a aa$ea a Pg <fa Dg$ySa`x a :fRa 4`a  f Ra "`Va #f Ra8`a`a ,fRaz`a `?a8"a`a^`aa/"azf/9/9B#`aL"9gN.A## _a`aa#C}E`:aF#CE<'`a _fR< a"_`Nu&?<JjDSD i ¼`0BAHA 42 HA2HAH@H@SDJfSDk < aQJj<-ak <0a`8NuBIxa< azB@`BBBa0 0e( 9b" d ҁҁҀҁҀRB`Nu  fR`NuA B< g<"g<'gJfaR`NuJf`ֲfB`ΰ<ae <zb< Nuag <f`B- M"pNB," pNBJ@f",y"pNB" pNBJ@f Mc" pNBJk`""MpBQ|T |B |I "M (:fAe6  <e,T`Rp  g .gQ @g QNuaha ,f.R/aV"_`aLa ,fRa:pap=ap /ap aJ`TaJg./"@N _`@a~/a =g& >fL =fRaNm$`&aHg` aBo`afR` ajB- .Bg FOR I=1 TO 100 PRINT I*I*I*I*I*I NEXT I N^NuNVH *n.P/ aBXO.Sa(@Pg n!l ``B.RaҾ l.-E` a,`p###,O` gf$O"NGa(.K`$a0e"@ 9gga` йi""9JjAm# y`a`` aJf"HBad`.y #X _/a` aeV$@`/ae.$@B"_a//9## / <:aVA.a$_$# _Xa ,f*R`  gaxa ,fR`a,yK\aeM"pNB" pNBJkB- " pNBJf(,y"pNB" pNBJfM` 9Єm#"`*9" eva ,yK\abe" pNB" pNBJkZB- M"pNB," pNBJ@f",y"pNB" pNBJ@f M"c" pNBJk`"MpBQ|T |B |I "M (:fAe6  <e,T`Rp  g .gQ @g QNuaha0 ,fJR/aV"_`aLa ,f.Ra:pap=ap /ap aJ`TaJgJ/"@N _`@a~/a =g& >fL =fRaNm$`&aHg` aBo`afR` ajB- .BgX=0 FOR I=0 TO 100000 CURSOR RND(22),RND(78) PRINT "*", NEXT I .- B .a *@Pf;| 9FTйV+@ n!mR/aDN a2a *fR/a""a`a /fVR/a "Aa`CnE`a6e"@B Nuap JBfa (fRaa )fRNuazB<@eBf(RHaЀeЀe/a"c 9&Nu< <eRH@@"9&ANu(JjDJjDc Abz4H@H@J@fjЂkdJjDNuJgV$(JjDJjDv"BҁрgkRQAJjDDNua "@BNuaJg k""yeC #a RNuaJjDkNuaJg/rTnR "Nu 9&"NuaeJ/a$ =f>RaN,_,Nua :fRX`a  fRX`tNua  fNu/MaD _ 9gHgB"ya`<?aB@San`/M`/M`a< aA.ag<g&<gD< g< eaj< g^}e<aT< aL.c<aa a ^(HA.a a BJAgVd YYa F*Ifa r$M&y"a z#" g&y",K 9&c R#""N$Ma N"H$M&La :`rLISLOANERUSAVNEXLEIGOTGOSURETURREFOINPUPRINPOKCURSOSTOBYCALPEERNABSIZSQTSTE VJ` < B f   X :>J 6 CEa &HBf K`$<.g<g X KBJj`tJj&RNa#"a` a y#JgB"H$y"Sae# ITa C0E`faraN"aRf`a a:a@ea a lg <fa `g$y"Sa2`x a :fRa P`a  f Ra >`Va #f Ra8`a`a ,fRa`a `?a8"a`az`a a/"af/9/9B#`ah"9gj.A## _a`aa#CE`:aF#C""Ha I"_< g|TNa 'fR<'`a _fR< a"_`Nu&?<JjDSD i ¼`0BAHA 42 HA2HAH@H@SDJfSDk < aQJj<-a~k <0ar`8NuBIxa< aXB@`BBBa0 0e( 9b" d ҁҁҀҁҀRB`Nu  fR`NuA.B< g<"g<'gJfaR`NuJf`ֲfB`ΰ<ae <zb< Nuag <f`NuMga`NuHApNCLNu/pNCJ@gpNC _Nu9AgCNu9Ag 9C<NuB@NBEGordo's MC68000 Tiny Basic, v1.0 ok how? what? sorry. )****************************************************************** * * * tiny basic for the motorola mc68000 * * * * derived from palo alto tiny basic as published in the may 1976 * * issue of dr. dobb's journal. adapted to the 68000 by: * * gordon brandly * * r.r. 2 * * fort sask., alberta, canada * * t8l 2n8 * * * * version 1.0 as of july 17, 1984 * * * * * * this version is for mex68kecb educational computer board i/o. * * * ****************************************************************** * copyright (c) 1984 by gordon brandly. this program may be * * freely distributed for personal use only. all commercial * * rights are reserved. * ****************************************************************** * CP/M-68K file and console I/O added by Dann Lunsford, * * Carmichael, CA, March 25, 1986 * ************************************** tst d1 does line no. exist? (or nonzero?) beq direct if not, it's a direct statement cmp.l #$ffff,d1 see if line no. is <= 16 bits bcc qhow if not, we've overflowed move.b d1,-(a0) store the binary line no. ror #8,d1 (kludge to store a word on a move.b d1,-(a0) possible byte boundary) rol #8,d1 bsr fndln find this line in save area move.l a1,a5 save possible line pointer bne st4 if not found, insert bsr fndnxt find the next line (into a1) move.l a5,a2 pointer to line to be deleted move.l txtunf,a3 points to top of save area bsr mvup move up to delete move.l a2,txtunf update the end pointer st4: move.l a4,d0 calculate the length of new line sub.l a0,d0 cmp.l #3,d0 is it just a line no. & cr? beq st3 if so, it was just a delete move.l txtunf,a3 compute new end move.l a3,a6 add.l d0,a3 move.l varbgn,d0 see if there's enough room cmp.l a3,d0 bls qsorry if not, say so move.l a3,txtunf if so, store new end position move.l a6,a1 points to old unfiBY',('E'+$80) .dc.b 'CAL',('L'+$80) .dc.b 0 tab4: .dc.b 'PEE',('K'+$80) functions .dc.b 'RN',('D'+$80) .dc.b 'AB',('S'+$80) .dc.b 'SIZ',('E'+$80) .dc.b 'SQ',('R'+$80) rev 1.1 .dc.b 0 tab5: .dc.b 'T',('O'+$80) "to" in "for" .dc.b 0 tab6: .dc.b 'STE',('P'+$80) "step" in "for" .dc.b 0 .even * execution address tables: tab1p1: .dc.l list direct commands .dc.l load .dc.l new .dc.l run .dc.l save tab2p1: .dc.l next direct / statement .dc.l let .dc.l if .dc.l goto .dc.l gosub .dc.l return .dc.l rem .dc.l for .dc.l input .dc.l print .dc.l poke .dc.l cursor added drl 25Mar86 .dc.l stoprun .dc.l gobye .dc.l call .dc.l deflt tab4p1: .dc.l peek functions .dc.l rnd .dc.l abs .dc.l size .dc.l sqrt rev 1.1 .dc.l xp40 tab5p1: .dc.l fr1 "to" in "for" .dc.l qwhat tab6p1: .dc.l fr2 "step" in "for" .dc.l fr3 * direct: lea tab1,a1 lea tab1p1,a2 exec: bsr ignblk ignore leading blanks move.l a0,a3 save the pointer c**************************** cr = $0d ascii equates lf = $0a tab = $09 ctrlc = $03 ctrlh = $08 ctrls = $13 ctrlx = $18 esc = $1b writef = $15 write sequential readf = $14 read sequential openf = $0f open file closef = $10 close file deletef = $13 delete file createf = $16 create file setdma = $1a set DMA address fcb = $5c offset for default fcb in base page buflen = 80 length of keyboard input buffer * * standard jump table. you can change these addresses if you are * customizing this interpreter for a different environment. * start: bra cstart cold start entry point gowarm: bra wstart warm start entry point goout: bra outchr jump to character-out routine goin: bra inchr jump to character-in routine goauxo: bra auxout jump to auxiliary-out routine goauxi: bra auxin jump to auxiliary-in routine gobye: bra byebye jump to monitor, dos, etc. * * modifiable system constants: * txtbgn: .dc.l txt beginning of program memory endmem: .dc.l 0 end of availablelled area move.l a5,a2 points to beginning of move area bsr mvdown move things out of the way move.l a0,a1 set up to do the insertion move.l a5,a2 move.l a4,a3 bsr mvup do it bra st3 go back and get another line * ******************************************************************* * * *** tables *** direct *** exec *** * * this section of the code tests a string against a table. when * a match is found, control is transferred to the section of * code according to the table. * * at 'exec', a0 should point to the string, a1 should point to * the character table, and a2 should point to the execution * table. at 'direct', a0 should point to the string, a1 and * a2 will be set up to point to tab1 and tab1p1, which are * the tables of all direct and statement commands. * * a '.' in the string will terminate the test and the partial * match will be considered as a match, e.g. 'p.', 'pr.','pri.', * 'prin.', or 'print' will all match 'print'. * * there are two tables: the charalr.b d2 clear match flag exlp: move.b (a0)+,d0 get the program character move.b (a1),d1 get the table character bne exngo if end of table, move.l a3,a0 restore the text pointer and... bra exgo execute the default. exngo: move.b d0,d3 else check for period... and.b d2,d3 and a match. cmp.b #'.',d3 beq exgo if so, execute and.b #$7f,d1 ignore the table's high bit cmp.b d0,d1 is there a match? beq exmat addq.l #4,a2 if not, try the next entry move.l a3,a0 reset the program pointer clr.b d2 sorry, no match ex1: tst.b (a1)+ get to the end of the entry bpl ex1 bra exlp back for more matching exmat: moveq #-1,d2 we've got a match so far tst.b (a1)+ end of table entry? bpl exlp if not, go back for more exgo: move.l (a2),a3 execute the appropriate routine jmp (a3) * ******************************************************************* * * what follows is the code to execute direct and statement * commands. control is transferred to these points via the com memory * * the main interpreter starts here: * cstart: move.l 4(sp),basepag save cp/m base page pointer move.l 4(sp),a0 get it to where we can use it move.l 4(a0),endmem top of the base page move.l 4(a0),sp initialize stack pointer lea initmsg,a6 tell who we are bsr prmesg move.l txtbgn,txtunf init. end-of-program pointer move.l endmem,d0 get address of end of memory sub.l #2048,d0 reserve 2k for the stack move.l d0,stklmt sub.l #108,d0 reserve variable area (27 long words) move.l d0,varbgn wstart: clr.l d0 initialize internal variables move.l d0,lopvar move.l d0,stkgos move.l d0,currnt current line number pointer = 0 move.l endmem,sp init s.p. again, just in case lea okmsg,a6 display "ok" bsr prmesg st3: move.b #'>',d0 prompt with a '>' and bsr getln read a line. bsr toupbuf convert to upper case move.l a0,a4 save pointer to end of line lea buffer,a0 point to the beginning of line bsr tstnum is there a number there? bsr ignblk skip trailing blanks cter table and the execution * table. the character table consists of any number of text items. * each item is a string of characters with the last character's * high bit set to one. the execution table holds a 16-bit * execution addresses that correspond to each entry in the * character table. * * the end of the character table is a 0 byte which corresponds * to the default routine in the execution table, which is * executed if none of the other table items are matched. * * character-matching tables: tab1: .dc.b 'LIS',('T'+$80) direct commands .dc.b 'LOA',('D'+$80) .dc.b 'NE',('W'+$80) .dc.b 'RU',('N'+$80) .dc.b 'SAV',('E'+$80) tab2: .dc.b 'NEX',('T'+$80) direct / statement .dc.b 'LE',('T'+$80) .dc.b 'I',('F'+$80) .dc.b 'GOT',('O'+$80) .dc.b 'GOSU',('B'+$80) .dc.b 'RETUR',('N'+$80) .dc.b 'RE',('M'+$80) .dc.b 'FO',('R'+$80) .dc.b 'INPU',('T'+$80) .dc.b 'PRIN',('T'+$80) .dc.b 'POK',('E'+$80) .dc.b 'CURSO',('R'+$80) added drl 25Mar86 .dc.b 'STO',('P'+$80) .dc.b '*mand * table lookup code of 'direct' and 'exec' in the last section. * after the command is executed, control is transferred to other * sections as follows: * * for 'list', 'new', and 'stop': go back to the warm start point. * for 'run': go execute the first stored line if any; else go * back to the warm start point. * for 'goto' and 'gosub': go execute the target line. * for 'return' and 'next'; go back to saved return line. * for all others: if 'currnt' is 0, go to warm start; else go * execute next command. (this is done in 'finish'.) * ******************************************************************* * * *** new *** stop *** run (& friends) *** goto *** * * 'new' sets txtunf to point to txtbgn * * 'stop' goes back to wstart * * 'run' finds the first stored line, stores its address * in currnt, and starts executing it. note that only those * commands in tab2 are legal for a stored program. * * there are 3 more entries in 'run': * 'runnxl' finds next line, stores it'serated after the entire list has been printed * or if the list is empty. if the list ends with a semicolon, * however, no is generated. * list: bsr tstnum see if there's a line no. bsr endchk if not, we get a zero bsr fndln find this or next line ls1: bcs wstart warm start if we passed the end bsr prtln print the line bsr chkio check for listing halt request beq ls3 cmp.b #ctrls,d0 pause the listing? bne ls3 ls2: bsr chkio if so, wait for another keypress beq ls2 ls3: move.l txtunf,a2 setup for search subq.l #1,a2 bsr fndlnp find the next line bra ls1 print: move #11,d4 d4 = number of print spaces bsr ignblk if null list and ":" cmpi.b #':',(a0) bne pr2 addq.l #1,a0 bsr crlf give cr-lf and continue bra runsml execution on the same line pr2: bsr ignblk if null list and cmpi.b #cr,(a0) bne pr0 addq.l #1,a0 bsr crlf also give cr-lf and bra runnxl execute the next line pr0: bsr ignblk else is it a format? cmpi.b #'#',(a0) re it move.l (sp)+,stkgos and the old 'stkgos' move.l (sp)+,currnt and the old 'currnt' move.l (sp)+,a0 and the old text pointer bsr popa and the old 'for' parameters bra finish and we are back home * ******************************************************************* * * *** for *** & next *** * * 'for' has two forms: * 'for var=exp1 to exp2 step exp1' and 'for var=exp1 to exp2' * the second form means the same thing as the first form with a * step of positive 1. the interpreter will find the variable 'var' * and set its value to the current value of 'exp1'. it also * evaluates 'exp2' and 'exp1' and saves all these together with * the text pointer, etc. in the 'for' save area, which consisits of * 'lopvar', 'lopinc', 'loplmt', 'lopln', and 'loppt'. if there is * already something in the save area (indicated by a non-zero * 'lopvar'), then the old save area is saved on the stack before * the new values are stored. the interpreter will then dig in the * stack and find out if  address and executes it. * 'runtsl' stores the address of this line and executes it. * 'runsml' continues the execution on same line. * * 'goto expr' evaluates the expression, finds the target * line, and jumps to 'runtsl' to do it. * new: bsr endchk move.l txtbgn,txtunf set the end pointer stoprun: bsr endchk bra wstart run: bsr endchk move.l txtbgn,a0 set pointer to beginning move.l a0,currnt runnxl: tst.l currnt executing a program? beq wstart if not, we've finished a direct stat. clr.l d1 else find the next line number move.l a0,a1 move.l txtunf,a2 setup for search subq.l #1,a2 bsr fndlnp bcs wstart if we've fallen off the end, stop runtsl: move.l a1,currnt set currnt to point to the line no. move.l a1,a0 set the text pointer to addq.l #2,a0 the start of the line text runsml: bsr chkio see if a control-c was pressed lea tab2,a1 find command in tab2 lea tab2p1,a2 bra exec and execute it goto: bsr expr evaluate the following expression  bne pr1 addq.l #1,a0 bsr expr yes, evaluate expression move d0,d4 and save it as print width bra pr3 look for more to print pr1: bsr qtstg is it a string? bra pr8 if not, must be an expression pr3: bsr ignblk if ",", go find next cmpi.b #',',(a0) bne pr6 addq.l #1,a0 bsr fin in the list. bra pr0 pr6: bsr crlf list ends here bra finish pr8: move d4,-(sp) save the width value bsr expr evaluate the expression move (sp)+,d4 restore the width move.l d0,d1 bsr prtnum print its value bra pr3 more to print? finish: bsr fin check end of command bra qwhat print "what?" if wrong * ******************************************************************* * * *** gosub *** & return *** * * 'gosub expr:' or 'gosub expr' is like the 'goto' command, * except that the current text pointer, stack pointer, etc. are * saved so that execution can be continued after the subroutine * 'return's. in order that 'gosub' can be nested (and even * recursive), the save areathis same variable was used in another * currently active 'for' loop. if that is the case, then the old * 'for' loop is deactivated. (i.e. purged from the stack) * * 'next var' serves as the logical (not necessarily physical) end * of the 'for' loop. the control variable 'var' is checked with * the 'lopvar'. if they are not the same, the interpreter digs in * the stack to find the right one and purges all those that didn't * match. either way, it then adds the 'step' to that variable and * checks the result with against the limit value. if it is within * the limit, control loops back to the command following the * 'for'. if it's outside the limit, the save area is purged and * execution continues. * for: bsr pusha save the old 'for' save area bsr setval set the control variable move.l a6,lopvar save its address lea tab5,a1 use 'exec' to test for 'to' lea tab5p1,a2 bra exec fr1: bsr expr evaluate the limit move.l d0,loplmt save that lea tab6,a1 use 'exec' to look for the bsr endchk must find end of line move.l d0,d1 bsr fndln find the target line bne qhow no such line no. bra runtsl go do it * ******************************************************************* * * *** list *** print *** * * list has two forms: * 'list' lists all saved lines * 'list #' starts listing at the line # * control-s pauses the listing, control-c stops it. * * print command is 'print ....:' or 'print ....' * where '....' is a list of expressions, formats, back-arrows, * and strings. these items a separated by commas. * * a format is a pound sign followed by a number. it controls * the number of spaces the value of an expression is going to * be printed in. it stays effective for the rest of the print * command unless changed by another format. if no format is * specified, 11 positions will be used. * * a string is quoted in a pair of single- or double-quotes. * * an underline (back-arrow) means generate a without a * * a is gen must be stacked. the stack pointer * is saved in 'stkgos'. the old 'stkgos' is saved on the stack. * if we are in the main routine, 'stkgos' is zero (this was done * in the initialization section of the interpreter), but we still * save it as a flag for no further 'return's. * * 'return' undoes everything that 'gosub' did, and thus * returns the execution to the command after the most recent * 'gosub'. if 'stkgos' is zero, it indicates that we never had * a 'gosub' and is thus an error. * gosub: bsr pusha save the current 'for' parameters bsr expr get line number move.l a0,-(sp) save text pointer move.l d0,d1 bsr fndln find the target line bne ahow if not there, say "how?" move.l currnt,-(sp) found it, save old 'currnt'... move.l stkgos,-(sp) and 'stkgos' clr.l lopvar load new values move.l sp,stkgos bra runtsl return: bsr endchk there should be just a move.l stkgos,d1 get old stack pointer beq qwhat if zero, it doesn't exist move.l d1,sp else resto+ lea tab6p1,a2 word 'step' bra exec fr2: bsr expr found it, get the step value bra fr4 fr3: moveq #1,d0 not found, step defaults to 1 fr4: move.l d0,lopinc save that too fr5: move.l currnt,lopln save address of current line number move.l a0,loppt and text pointer move.l sp,a6 dig into the stack to find 'lopvar' bra fr7 fr6: add.l #20,a6 look at next stack frame fr7: move.l (a6),d0 is it zero? beq fr8 if so, we're done cmp.l lopvar,d0 same as current lopvar? bne fr6 nope, look some more move.l sp,a2 else remove 5 long words from... move.l a6,a1 inside the stack. lea 20,a3 add.l a1,a3 bsr mvdown move.l a3,sp set the sp 5 long words up fr8: bra finish and continue execution next: bsr tstv get address of variable bcs qwhat if no variable, say "what?" move.l d0,a1 save variable's address nx0: move.l lopvar,d0 if 'lopvar' is zero, we never... beq qwhat had a for loop, so say "what?" cmp.l d0,a1 else we check them beq nx3 ok, they agree bsr popa inperr'. * * 'let' is followed by a list of items separated by commas. * each item consists of a variable, an equals sign, and an * expression. the interpreter evaluates the expression and sets * the variable to that value. the interpreter will also handle * 'let' commands without the word 'let'. this is done by 'deflt'. * rem: bra if2 skip the rest of the line if: bsr expr evaluate the expression if1: tst.l d0 is it zero? bne runsml if not, continue if2: move.l a0,a1 clr.l d1 bsr fndskp if so, skip the rest of the line bcc runtsl and run the next line bra wstart if no next line, do a warm start inperr: move.l stkinp,sp restore the old stack pointer move.l (sp)+,currnt and old 'currnt' addq.l #4,sp move.l (sp)+,a0 and old text pointer input: move.l a0,-(sp) save in case of error bsr qtstg is next item a string? bra ip2 nope bsr tstv yes, but is it followed by a variable? bcs ip4 if not, branch move.l d0,a2 put away the variable's address bra ip3 inn Lunsford, 25Mar86 * load: bsr ignblk move.l basepag,a6 lea fcb(a6),a5 bsr fcbset bcs qwhat lea $80(a6),a6 move.l a6,d1 moveq #setdma,d0 trap #2 move.l a5,d1 moveq #openf,d0 trap #2 tst.b d0 bmi qhow clr.b 32(a5) move.l a5,d1 moveq #readf,d0 trap #2 read header sector tst.b d0 bne qsorry move.l (a6),d4 save program length move.l txtbgn,a6 .rloop: move.l a6,d1 moveq #setdma,d0 trap #2 set buffer addr move.l a5,d1 moveq #readf,d0 trap #2 read one sector's worth of program tst.b d0 bne .rclose lea 128(a6),a6 bra .rloop .rclose: move.l txtbgn,d0 add.l d4,d0 cmpa.l d0,a6 blt qsorry move.l d0,txtunf bra wstart save: move.l txtunf,d5 compute length of program sub.l txtbgn,d5 cmpi.l #5,d5 smallest possible valid program bcs qsorry unable to comply bsr ignblk skip blanks in command move.l basepag,a6 use default fcb lea fcb(a6),a5 point at it bsr fcbset a0 points at string, a5 at fcb bcs qwhat bad filename monope, let's see the next frame bra nx0 nx3: move.l (a1),d0 get control variable's value add.l lopinc,d0 add in loop increment bvs qhow say "how?" for 32-bit overflow move.l d0,(a1) save control variable's new value move.l loplmt,d1 get loop's limit value tst.l lopinc bpl nx1 branch if loop increment is positive exg d0,d1 nx1: cmp.l d0,d1 test against limit blt nx2 branch if outside limit move.l lopln,currnt within limit, go back to the... move.l loppt,a0 saved 'currnt' and text pointer. bra finish nx2: bsr popa purge this loop bra finish * ******************************************************************* * * *** rem *** if *** input *** let (& deflt) *** * * 'rem' can be followed by anything and is ignored by the * interpreter. * * 'if' is followed by an expression, as a condition and one or * more commands (including other 'if's) separated by colons. * note that the word 'then' is not used. the interpreter evaluates * the expression. if it is non-zero, exf so, input to variable ip2: move.l a0,-(sp) save for 'prtstg' bsr tstv must be a variable now bcs qwhat "what?" it isn't? move.l d0,a2 put away the variable's address move.b (a0),d2 get ready for 'prtstg' clr.b d0 move.b d0,(a0) move.l (sp)+,a1 bsr prtstg print string as prompt move.b d2,(a0) restore text ip3: move.l a0,-(sp) save in case of error move.l currnt,-(sp) also save 'currnt' move.l #-1,currnt flag that we are in input move.l sp,stkinp save the stack pointer too move.l a2,-(sp) save the variable address move.b #':',d0 print a colon first bsr getln then get an input line lea buffer,a0 point to the buffer bsr expr evaluate the input move.l (sp)+,a2 restore the variable address move.l d0,(a2) save value in variable move.l (sp)+,currnt restore old 'currnt' move.l (sp)+,a0 and the old text pointer ip4: addq.l #4,sp clean up the stack bsr ignblk is the next thing a comma? cmpi.b #',',(a0) bne finish addq.l #1,a0 bra input yes, more itemsve.l a5,d1 set up for system call moveq #deletef,d0 delete old file if present trap #2 move.l a5,d1 set up for create moveq #createf,d0 trap #2 tst.b d0 bmi qhow can't create clr.b 32(a5) set current record field, file is open lea $80(a6),a6 point at default buffer move.l a6,d1 but it might have been changed moveq #setdma,d0 trap #2 move.l d5,(a6) set length into header record move.l a5,d1 moveq #writef,d0 trap #2 write header tst d0 bne closfile move.l txtbgn,a6 beginning of program buffer sloop: move.l a6,d1 set dma moveq #setdma,d0 trap #2 move.l a5,d1 moveq #writef,d0 trap #2 write program block tst d0 bne closfile lea 128(a6),a6 bump dma pointer cmpa.l txtunf,a6 done? bls sloop no, go write next record closfile: move.l a5,d1 moveq #closef,d0 trap #2 tst.b d0 bmi qhow bra wstart * fcbset builds a CP/M-68K FCB in the place that a5 points at, out * of the string that a0 points at. File type is forced to TBI. * returnecution continues. if it * is zero, the commands that follow are ignored and execution * continues on the next line. * * 'input' is like the 'print' command, and is followed by a list * of items. if the item is a string in single or double quotes, * or is an underline (back arrow), it has the same effect as in * 'print'. if an item is a variable, this variable name is * printed out followed by a colon, then the interpreter waits for * an expression to be typed in. the variable is then set to the * value of this expression. if the variable is preceeded by a * string (again in single or double quotes), the string will be * displayed followed by a colon. the interpreter the waits for an * expression to be entered and sets the variable equal to the * expression's value. if the input expression is invalid, the * interpreter will print "what?", "how?", or "sorry" and reprint * the prompt and redo the input. the execution will not terminate * unless you press control-c. this is handled in ' deflt: cmp.b #cr,(a0) empty line is ok beq finish else it is 'let' let: bsr setval do the assignment bsr ignblk check for more 'let' items cmpi.b #',',(a0) bne finish addq.l #1,a0 bra let * ******************************************************************* * * *** load *** & save *** * * These commands save and restore a program to/from CP/M-68K disk files. * Syntax is: * LOAD FILENAME * SAVE FILENAME * Limitations are (currently) that the file type is forced to TBI, and * that the filename is not checked extensively for validity. The format * of a saved BASIC program file is a one-sector header, which contains in * its first four bytes, the length of the program's core image. The * remaining sectors of the file are a core image of the program space * (line numbers in binary, CR only at end of line). This is easiest * to program. It does, however, preclude the use of a full-screen editor * for program preparation. Think about building one for this BASIC. * Da,s C set if something is uncool. A5 is unchanged on return * a0 has been advanced to point to the last valid char for the fcb fcbset: move.l a5,a1 moveq #32-1,d0 .cloop: clr.b (a1)+ dbra d0,.cloop move.b #'T',9(a5) move.b #'B',10(a5) move.b #'I',11(a5) move.l a5,a1 cmpi.b #':',1(a0) drive present? bne .fcbs1 nope move.b (a0),d0 subi.b #'A',d0 whole buffer was touppered, remember? bcs .fcbex whoops! cmpi.b #'P'-'A'+1,d0 eori #1,ccr bcs .fcbex move.b d0,(a1)+ store drive addq.l #2,a0 bump past D: bra .fcbs2 .fcbs1: addq.l #1,a1 .fcbs2: moveq #8-1,d0 8 chars max .fcbs3: move.b (a0)+,d1 get char cmpi.b #cr,d1 end of line? beq .fcbol yep cmpi.b #'.',d1 alien filetype? beq .fcbol move.b d1,(a1)+ dbra d0,.fcbs3 .fcbol: cmpi #-1,d0 beq .fcbex .fcbl1: move.b #$20,(a1)+ fill in rest of fcb dbra d0,.fcbl1 .fcbex: rts * ******************************************************************* * * *** poke *** & call *** & cursor *** * * 'poke expr1,::=( <* or /> )(... * ::= * * () * is recursive so that the variable '@' can have an * as an index, functions can have an as arguments, and * can be an in parenthesis. * expr: bsr expr2 move.l d0,-(sp) save value * added per ddj #106 bsr ignblk skip blanks move.b (a0)+,d2 get first char cmpi.b #'=',d2 equals beq xp15 yes, go process * cmpi.b #'>',d2 >, or >=? bne xxp1 no * cmpi.b #'=',(a0) >=? bne xp13 no, process > * addq.l #1,a0 skip past = xp11: bsr xp18 is it ">="? blt xprt0 no, return d0=0 bra xprt1 else return d0=1 xp12: bsr xp18 is it "<>"? beq xprt0 no, return d0=0 bra xprt1 else return d0=1 xp13: bsr xp18 is it ">"? ble xprt0 no, return d0=0 bra xprt1 else return d0=1 xp14: bsr xp18 is it "<="? bgt xprt0 no, return d0=0 bra xprt1 else return d0=1 xp15: bsr xp18 is it "="? bne xprt0 if not, return d0=0 bra xprt1 els)+,d1 exg d0,d1 bsr div32 do the division bra xp31 go back for any more terms expr4: lea tab4,a1 find possible function lea tab4p1,a2 bra exec xp40: bsr tstv nope, not a function bcs xp41 nor a variable move.l d0,a1 clr.l d0 move.l (a1),d0 if a variable, return its value in d0 exp4rt: rts xp41: bsr tstnum or is it a number? move.l d1,d0 tst d2 (if not, # of digits will be zero) bne exp4rt if so, return it in d0 parn: bsr ignblk else look for ( expr ) cmpi.b #'(',(a0) bne qwhat addq.l #1,a0 bsr expr bsr ignblk cmpi.b #')',(a0) bne qwhat addq.l #1,a0 xp42: rts * * ===== test for a valid variable name. returns carry=1 if not * found, else returns carry=0 and the address of the * variable in d0. tstv: bsr ignblk clr.l d0 move.b (a0),d0 look at the program text sub.b #'@',d0 bcs tstvrt c=1: not a variable bne tv1 branch if not "@" array addq #1,a0 if it is, it should be bsr parn followed by (expr) as its index. add.l d0,d0 bexpr2' stores the byte from 'expr2' into the memory * address specified by 'expr1'. * * 'call expr' jumps to the machine language subroutine whose * starting address is specified by 'expr'. the subroutine can use * all registers but must leave the stack the way it found it. * the subroutine returns to the interpreter by executing an rts. * * 'cursor expr1,expr2' positions the cursor on the terminal screen * expr1 is the row co-ordinate, and expr2 is the column. * note: No checking is done for proper range of row or column. * Contains terminal dependent code, must be altered if ported to * a different terminal. * poke: bsr expr get the memory address bsr ignblk it must be followed by a comma cmpi.b #',',(a0) bne qwhat addq.l #1,a0 move.l d0,-(sp) save the address bsr expr get the byte to be poke'd move.l (sp)+,a1 get the address back move.b d0,(a1) store the byte in memory bra finish cursor: bsr expr get the row coord bsr ignblk must be followed by a comma cmpi.b e return d0=1 xp15rt: rts xp16: bsr xp18 is it "<"? bge xprt0 if not, return d0=0 bra xprt1 else return d0=1 xp16rt: rts xprt0: clr.l d0 return d0=0 (false) rts xprt1: moveq #1,d0 return d0=1 (true) rts * added per ddj #106 xxp2: cmpi.b #'=',(a0) <=? bne xxp3 no addq.l #1,a0 bra xp14 process <= xxp3: cmpi.b #'>',(a0) <>? bne xp16 no, process < addq.l #1,a0 skip past > bra xp12 process <> xxp1: cmpi.b #'<',d2 <, <=, or <>? beq xxp2 no subq.l #1,a0 default case, so drop through and handle xp17: move.l (sp)+,d0 it's not a rel. operator rts return d0= xp18: move.l (sp)+,d0 reverse the top two stack items move.l (sp)+,d1 move.l d0,-(sp) move.l d1,-(sp) bsr expr2 do second move.l (sp)+,d1 cmp.l d0,d1 compare with the first result rts return the result expr2: bsr ignblk negative sign? cmpi.b #'-',(a0) bne xp21 addq.l #1,a0 clr.l d0 yes, fake '0-' bra xp26 xp21: bsr ignblk positive sign? ignore it cmpi.b #'cs qhow say "how?" if index is too big add.l d0,d0 bcs qhow move.l d0,-(sp) save the index bsr size get amount of free memory move.l (sp)+,d1 get back the index cmp.l d1,d0 see if there's enough memory bls qsorry if not, say "sorry" move.l varbgn,d0 put address of array element... sub.l d1,d0 into d0 rts tv1: cmp.b #27,d0 if not @, is it a through z? eori #1,ccr bcs tstvrt if not, set carry and return addq #1,a0 else bump the text pointer add d0,d0 compute the variable's address add d0,d0 move.l varbgn,d1 add d1,d0 and return it in d0 with carry=0 tstvrt: rts * * ===== multiplies the 32 bit values in d0 and d1, returning * the 32 bit result in d0. * mult32: move.l d1,d4 eor.l d0,d4 see if the signs are the same tst.l d0 take absolute value of d0 bpl mlt1 neg.l d0 mlt1: tst.l d1 take absolute value of d1 bpl mlt2 neg.l d1 mlt2: cmp.l #$ffff,d1 is second argument <= 16 bits? bls mlt3 ok, let it through exg d0,d1 else swap the two argume#',',(a0) bne qwhat addq.l #1,a0 move.b d0,-(sp) save row bsr expr get column move.b d0,-(sp) save column moveq #$1b,d0 cursor position lead in bsr goout moveq #$3d,d0 bsr goout moveq #$20,d0 add.b 2(sp),d0 bsr goout moveq #$20,d0 add.b (sp),d0 bsr goout tst.l (sp)+ bra finish call: bsr expr get the subroutine's address tst.l d0 make sure we got a valid address beq qhow if not, say "how?" move.l a0,-(sp) save the text pointer move.l d0,a1 jsr (a1) jump to the subroutine move.l (sp)+,a0 restore the text pointer bra finish * ******************************************************************* * * *** expr *** * * 'expr' evaluates arithmetical or logical expressions. * ::= * * where is one of the operators in tab8 and the result * of these operations is 1 if true and 0 if false. * ::=(+ or -)(+ or -)(... * where () are optional and (... are optional repeats. * +',(a0) bne xp22 addq.l #1,a0 xp22: bsr expr3 first xp23: bsr ignblk add? cmpi.b #'+',(a0) bne xp25 addq.l #1,a0 move.l d0,-(sp) yes, save the value bsr expr3 get the second xp24: move.l (sp)+,d1 add.l d1,d0 add it to the first bvs qhow branch if there's an overflow bra xp23 else go back for more operations xp25: bsr ignblk subtract? cmpi.b #'-',(a0) bne xp42 addq.l #1,a0 xp26: move.l d0,-(sp) yes, save the result of 1st bsr expr3 get second neg.l d0 change its sign jmp xp24 and do an addition expr3: bsr expr4 get first xp31: bsr ignblk multiply? cmpi.b #'*',(a0) bne xp34 addq.l #1,a0 move.l d0,-(sp) yes, save that first result bsr expr4 get second move.l (sp)+,d1 bsr mult32 multiply the two bra xp31 then look for more terms xp34: bsr ignblk divide? cmpi.b #'/',(a0) bne xp42 addq.l #1,a0 move.l d0,-(sp) save result of 1st bsr expr4 get second move.l (sp-nts cmp.l #$ffff,d1 and check 2nd argument again bhi qhow one of them must be 16 bits mlt3: move d0,d2 prepare for 32 bit x 16 bit multiply mulu d1,d2 multiply low word swap d0 mulu d1,d0 multiply high word swap d0 *********** multiply overflow fix ********** rev 1.1 tst d0 test for overflow bne qhow add.l d2,d0 d0 now holds the product * if sign bit set after add then overflow bmi qhow if overflow, say "how?" ******************************************** tst.l d4 were the signs the same? bpl mltret neg.l d0 if not, make the result negative mltret: rts * * ===== divide the 32 bit value in d0 by the 32 bit value in d1. * returns the 32 bit quotient in d0, remainder in d1. * div32: tst.l d1 check for divide-by-zero beq qhow if so, say "how?" move.l d1,d2 move.l d1,d4 eor.l d0,d4 see if the signs are the same tst.l d0 take absolute value of d0 bpl div1 neg.l d0 div1: tst.l d1 take absolute value of d1 bpl div2 neg.l d1 div2: moveq #31,d3 : move.l varbgn,d0 get the number of free bytes... sub.l txtunf,d0 between 'txtunf' and 'varbgn' rts return the number in d0 * ******************************************************************* * * *** setval *** fin *** endchk *** error (& friends) *** * * 'setval' expects a variable, followed by an equal sign and then * an expression. it evaluates the expression and sets the variable * to that value. * * 'fin' checks the end of a command. if it ended with ":", * execution continues. if it ended with a cr, it finds the * the next line and continues from there. * * 'endchk' checks if a command is ended with a cr. this is * required in certain commands, such as goto, return, stop, etc. * * 'error' prints the string pointed to by a0. it then prints the * line pointed to by currnt with a "?" inserted at where the * old text pointer (should be on top of the stack) points to. * execution of tiny basic is stopped and a warm start is done. * if currnt is zero (indicating a direct com ahow: lea howmsg,a6 bra error * ******************************************************************* * * *** getln *** fndln (& friends) *** * * 'getln' reads in input line into 'buffer'. it first prompts with * the character in d0 (given by the caller), then it fills the * buffer and echos. it ignores lf's but still echos * them back. control-h is used to delete the last character * entered (if there is one), and control-x is used to delete the * whole line and start over again. cr signals the end of a line, * and causes 'getln' to return. * * 'fndln' finds a line with a given line no. (in d1) in the * text save area. a1 is used as the text pointer. if the line * is found, a1 will point to the beginning of that line * (i.e. the high byte of the line no.), and flags are nc & z. * if that line is not there and a line with a higher line no. * is found, a1 points there and flags are nc & nz. if we reached * the end of the text save area and cannot find the line, flags * are c & nz. * 'fniteration count for 32 bits move.l d0,d1 clr.l d0 div3: add.l d1,d1 (this algorithm was translated from addx.l d0,d0 the divide routine in ron cain's beq div4 small-c run time library.) cmp.l d2,d0 bmi div4 addq.l #1,d1 sub.l d2,d0 div4: dbra d3,div3 exg d0,d1 put rem. & quot. in proper registers tst.l d4 were the signs the same? bpl divrt neg.l d0 if not, results are negative neg.l d1 divrt: rts * * ===== the peek function returns the byte stored at the address * contained in the following expression. * peek: bsr parn get the memory address move.l d0,a1 clr.l d0 upper 3 bytes will be zero move.b (a1),d0 get the addressed byte rts and return it * * ===== the rnd function returns a random number from 1 to * the value of the following expression in d0. * rnd: bsr parn get the upper limit tst.l d0 it must be positive and non-zero beq qhow bmi qhow move.l d0,d1 move.l ranpnt,a1 get memory as a random number cmp.l #lstrom,a1 bcs ra1 lemand), the direct * command is not printed. if currnt is -1 (indicating * 'input' command in progress), the input line is not printed * and execution is not terminated but continues at 'inperr'. * * related to 'error' are the following: * 'qwhat' saves text pointer on stack and gets "what?" message. * 'awhat' just gets the "what?" message and jumps to 'error'. * 'qsorry' and 'asorry' do the same kind of thing. * 'qhow' and 'ahow' also do this for "how?". * setval: bsr tstv variable name? bcs qwhat if not, say "what?" move.l d0,-(sp) save the variable's address bsr ignblk get past the "=" sign cmpi.b #'=',(a0) bne qwhat addq.l #1,a0 bsr expr evaluate the expression move.l (sp)+,a6 move.l d0,(a6) and save its value in the variable rts fin: bsr ignblk *** fin *** cmpi.b #':',(a0) bne fi1 addq.l #1,a0 addq.l #4,sp if ":", discard return address bra runsml continue on the same line fi1: bsr ignblk not ":", is it a cr? cmpi.b #cr,(a0) bne fi2 addq.l #1,a0 dln' will initialize a1 to the beginning of the text save * area to start the search. some other entries of this routine * will not initialize a1 and do the search. * 'fndlnp' will start with a1 and search for the line no. * 'fndnxt' will bump a1 by 2, find a cr and then start search. * 'fndskp' uses a1 to find a cr, and then starts the search. * getln: bsr goout display the prompt move.b #' ',d0 and a space bsr goout lea buffer,a0 a0 is the buffer pointer gl1: bsr chkio check keyboard beq gl1 wait for a char. to come in cmp.b #ctrlh,d0 delete last character? beq gl3 if so cmp.b #ctrlx,d0 delete the whole line? beq gl4 if so cmp.b #cr,d0 accept a cr beq gl2 cmp.b #' ',d0 if other control char., discard it bcs gl1 gl2: move.b d0,(a0)+ save the char. bsr goout echo the char back out cmp.b #cr,d0 if it's a cr, end the line beq gl7 cmp.l #(buffer+buflen-1),a0 any more room? bcs gl1 yes: get some more, else delete last char. gl3: move.b #ctrlh,d0 delete a chara start,a1 wrap around if end of program ra1: move.l (a1)+,d0 get the slightly random number bclr #31,d0 make sure it's positive move.l a1,ranpnt (even i can do better than this!) bsr div32 rnd(n)=mod(number,n)+1 move.l d1,d0 mod is the remainder of the div. addq.l #1,d0 rts * * ===== the abs function returns an absolute value in d0. * abs: bsr parn get the following expr.'s value tst.l d0 bpl absrt neg.l d0 if negative, complement it bmi qhow if still negative, it was too big absrt: rts * * * ===== the sqr function returns the integer square root of d0 * sqrt: bsr parn get argument tst.l d0 is argument 0? beq sqrtn yes, so return * move.l d1,-(a7) save d1 moveq #-1,d1 initialize odd sqrtlp: addq.l #2,d1 next odd init sub.l d1,d0 done yet? bgt sqrtlp if not, loop * addq.l #1,d1 round up lsr.l d1 move.l d1,d0 return in d0 move.l (a7)+,d1 restore d1 sqrtn: rts * * ===== the size function returns the size of free memory in d0. * size addq.l #4,sp yes, purge return address bra runnxl execute the next line fi2: rts else return to the caller endchk: bsr ignblk cmp.b #cr,(a0) does it end with a cr? bne qwhat if not, say "what?" rts qwhat: move.l a0,-(sp) awhat: lea whtmsg,a6 error: bsr prmesg display the error message move.l (sp)+,a0 restore the text pointer move.l currnt,d0 get the current line number beq wstart if zero, do a warm start cmp.l #-1,d0 is the line no. pointer = -1? beq inperr if so, redo input move.b (a0),-(sp) save the char. pointed to clr.b (a0) put a zero where the error is move.l currnt,a1 point to start of current line bsr prtln display the line in error up to the 0 move.b (sp)+,(a0) restore the character move.b #'?',d0 display a "?" bsr goout clr d0 subq.l #1,a1 point back to the error char. bsr prtstg display the rest of the line bra wstart and do a warm start qsorry: move.l a0,-(sp) asorry: lea srymsg,a6 bra error qhow: move.l a0,-(sp) error: "how?" .. if possible bsr goout move.b #' ',d0 bsr goout cmp.l #buffer,a0 any char.'s left? bls gl1 if not move.b #ctrlh,d0 if so, finish the bs-space-bs sequence bsr goout subq.l #1,a0 decrement the text pointer bra gl1 back for more gl4: move.l a0,d1 delete the whole line sub.l #buffer,d1 figure out how many backspaces we need beq gl6 if none needed, branch subq #1,d1 adjust for dbra gl5: move.b #ctrlh,d0 and display bs-space-bs sequences bsr goout move.b #' ',d0 bsr goout move.b #ctrlh,d0 bsr goout dbra d1,gl5 gl6: lea buffer,a0 reinitialize the text pointer bra gl1 and go back for more gl7: move.b #lf,d0 echo a lf for the cr bsr goout rts fndln: cmp.l #$ffff,d1 line no. must be < 65535 bcc qhow move.l txtbgn,a1 init. the text save pointer move.l txtunf,a2 check if we passed the end subq.l #1,a2 fndlnp: cmp.l a1,a2 change per ddj #106 bcs fndret if so, return with z=0 & c=1 move.b (a1),d2 if not, get a line no. lsl.l #8,d2 move.b returns * to the caller. if underline, outputs a cr without a lf. if single * or double quote, prints the quoted string and demands a matching * end quote. after the printing, the next 2 bytes of the caller are * skipped over (usually a short branch instruction). * * 'prtnum' prints the 32 bit number in d1, leading blanks are added if * needed to pad the number of spaces to the number in d4. * however, if the number of digits is larger than the no. in * d4, all digits are printed anyway. negative sign is also * printed and counted in, positive sign is not. * * 'prtln' prints the saved text line pointed to by a1 * with line no. and all. * prtstg: move.b d0,d1 save the stop character ps1: move.b (a1)+,d0 get a text character cmp.b d0,d1 same as stop character? beq prtret if so, return bsr goout display the char. cmp.b #cr,d0 is it a c.r.? bne ps1 no, go back for more move.b #lf,d0 yes, add a l.f. bsr goout prtret: rts then return qtstg: bsr ignblk *** qtstg *** c pnret: move (sp)+,d4 restore width value rts prtln: clr.l d1 move.b (a1)+,d1 get the binary line number lsl #8,d1 move.b (a1)+,d1 moveq #5,d4 display a 5 digit line no. bsr prtnum move.b #' ',d0 followed by a blank bsr goout clr d0 stop char. is a zero bra prtstg display the rest of the line * * ===== see if the text pointed to by a0 is a number. if so, * return the number in d1 and the number of digits in d2, * else return zero in d1 and d2. * tstnum: clr.l d1 initialize return parameters clr d2 bsr ignblk skip over blanks tn1: cmp.b #'0',(a0) is it less than zero? bcs tsnmret if so, that's all cmp.b #'9',(a0) is it greater than nine? bhi tsnmret if so, return cmp.l #214748364,d1 see if there's room for new digit bcc qhow if not, we've overflowd move.l d1,d0 quickly multiply result by 10 add.l d1,d1 add.l d1,d1 add.l d0,d1 add.l d1,d1 move.b (a0)+,d0 add in the new digit and.l #$f,d0 add.l d0,d1 addq #1,d2 increment the no. of digit1(a1),d2 cmp d1,d2 is this the line we want? bcc fndret no, not there yet f1: addq.l #2,a1 f2: cmpi.b #cr,(a1)+ bne f2 bra fndlnp fndret: rts return the cond. codes fndnxt: move.l txtunf,a2 subq.l #1,a2 find the next line bra f1 fndskp: move.l txtunf,a2 subq.l #1,a2 bra f2 * ******************************************************************* * * *** mvup *** mvdown *** popa *** pusha *** * * 'mvup' moves a block up from where a1 points to where a2 points * until a1=a3 * * 'mvdown' moves a block down from where a1 points to where a3 * points until a1=a2 * * 'popa' restores the 'for' loop variable save area from the stack * * 'pusha' stacks for 'for' loop variable save area onto the stack * mvup: cmp.l a1,a3 see the above description beq mvret move.b (a1)+,(a2)+ bra mvup mvret: rts mvdown: cmp.l a1,a2 see the above description beq mvret move.b -(a1),-(a3) bra mvdown popa: move.l (sp)+,a6 a6 = return address move.l (sp)+,lopvar restore lopvarmpi.b #'"',(a0) bne qt3 addq.l #1,a0 move.b #'"',d0 it is a " qt1: move.l a0,a1 bsr prtstg print until another move.l a1,a0 move.l (sp)+,a1 pop return address cmp.b #lf,d0 was last one a cr? beq runnxl if so, run next line qt2: addq.l #2,a1 skip 2 bytes on return jmp (a1) return qt3: bsr ignblk is it a single quote? cmpi.b #'''',(a0) bne qt4 addq.l #1,a0 move.b #'''',d0 if so, do same as above bra qt1 qt4: bsr ignblk is it an underline? cmpi.b #'_',(a0) bne qt5 addq.l #1,a0 move.b #cr,d0 if so, output a cr without lf bsr goout move.l (sp)+,a1 pop return address bra qt2 qt5: rts none of the above prtnum: move.l d1,d3 save the number for later move d4,-(sp) save the width value move.b #$ff,-(sp) flag for end of digit string tst.l d1 is it negative? bpl pn1 if not neg.l d1 else make it positive subq #1,d4 one less for width count pn1: divu #10,d1 get the next digit bvs pnov overflow flag set? move.l d1,d0 if not, save remainders bra tn1 tsnmret: rts * * ===== skip over blanks in the text pointed to by a0. * ignblk: cmp.b #' ',(a0) see if it's a space bne igbret if so, swallow it igb1: addq.l #1,a0 increment the text pointer bra ignblk igbret: rts * * ===== convert the line of text in the input buffer to upper * case (except for stuff between quotes). * toupbuf: lea buffer,a0 set up text pointer clr.b d1 clear quote flag toupb1: move.b (a0)+,d0 get the next text char. cmp.b #cr,d0 is it end of line? beq toupbrt if so, return cmp.b #'"',d0 a double quote? beq doquo cmp.b #'''',d0 or a single quote? beq doquo tst.b d1 inside quotes? bne toupb1 if so, do the next one bsr toupper convert to upper case move.b d0,-(a0) store it addq.l #1,a0 bra toupb1 and go back for more toupbrt: rts doquo: tst.b d1 are we inside quotes? bne doquo1 move.b d0,d1 if not, toggle inside-quotes flag bra toupb1 doquo1: cmp.b d0,d1 make sure we're ending proper quote bne toupb1 if not, , but zero means no more beq pp1 move.l (sp)+,lopinc if not zero, restore the rest move.l (sp)+,loplmt move.l (sp)+,lopln move.l (sp)+,loppt pp1: jmp (a6) return pusha: move.l stklmt,d1 are we running out of stack room? sub.l sp,d1 bcc qsorry if so, say we're sorry move.l (sp)+,a6 else get the return address move.l lopvar,d1 save loop variables beq pu1 if lopvar is zero, that's all move.l loppt,-(sp) else save all the others move.l lopln,-(sp) move.l loplmt,-(sp) move.l lopinc,-(sp) pu1: move.l d1,-(sp) jmp (a6) return * ******************************************************************* * * *** prtstg *** qtstg *** prtnum *** prtln *** * * 'prtstg' prints a string pointed to by a1. it stops printing * and returns to the caller when either a cr is printed or when * the next byte is the same as what was passed in d0 by the * caller. * * 'qtstg' looks for an underline (back-arrow on some systems), * single-quote, or double-quote. if none of these are found,  and.l #$ffff,d1 strip the remainder bra toascii skip the overflow stuff pnov: move d1,d0 prepare for long word division clr.w d1 zero out low word swap d1 high word into low divu #10,d1 divide high word move d1,d2 save quotient move d0,d1 low word into low divu #10,d1 divide low word move.l d1,d0 d0 = remainder swap d1 r/q becomes q/r move d2,d1 d1 is low/high swap d1 d1 is finally high/low toascii: swap d0 get remainder move.b d0,-(sp) stack it as a digit swap d0 subq #1,d4 decrement width count tst.l d1 if quotient is zero, we're done bne pn1 subq #1,d4 adjust padding count for dbra bmi pn4 skip padding if not needed pn3: move.b #' ',d0 display the required leading spaces bsr goout dbra d4,pn3 pn4: tst.l d3 is number negative? bpl pn5 move.b #'-',d0 if so, display the sign bsr goout pn5: move.b (sp)+,d0 now unstack the digits and display bmi pnret until the flag code is reached add.b #'0',d0 make into ascii bsr goout bra pn5/ignore it clr.b d1 else clear quote flag bra toupb1 * * ===== convert the character in d0 to upper case * toupper: cmp.b #'a',d0 is it < 'a'? bcs toupret cmp.b #'z',d0 or > 'z'? bhi toupret sub.b #32,d0 if not, make it upper case toupret: rts * * 'chkio' checks the input. if there's no input, it will return * to the caller with the z flag set. if there is input, the z * flag is cleared and the input byte is in d0. however, if a * control-c is read, 'chkio' will warm-start basic and will not * return to the caller. * chkio: bsr goin get input if possible beq chkret if zero, no input cmp.b #ctrlc,d0 is it control-c? bne chkret if not bra wstart if so, do a warm start chkret: rts * * ===== display a cr-lf sequence * crlf: lea clmsg,a6 * * ===== display a zero-ended string pointed to by register a6 * prmesg: move.b (a6)+,d0 get the char. beq prmret if it's zero, we're done bsr goout else display it bra prmesg prmret: rts ***********************currnt: .ds.l 1 current line pointer stkgos: .ds.l 1 saves stack pointer in 'gosub' stkinp: .ds.l 1 saves stack pointer during 'input' lopvar: .ds.l 1 'for' loop save area lopinc: .ds.l 1 increment loplmt: .ds.l 1 limit lopln: .ds.l 1 line number loppt: .ds.l 1 text pointer txtunf: .ds.l 1 points to unfilled text area varbgn: .ds.l 1 points to variable area stklmt: .ds.l 1 holds lower limit for stack growth buffer: .ds.b buflen keyboard input buffer .even txt = * beginning of program area .end  lower limit for stack growth buffer: .ds.b buflen keyboard input buffer .even txt = * beginning of prog#a`.a`J@gڰ|g|g.aNJLN^NuNVH*n.6Bg?<N XO.Bg?<N XO|m>ajB- .BgdLET C = 8323104 nLET D= C + 1 xLET G= 00 POKE C,G LET H = 128 LET J = 192 "POKE C,H ,FOR L = 1 TO 13 6POKE C,J @LET V = PEEK(D) JPRINT J,V-240 TFOR N = 1 TO 100 YNEXT N ^POKE C,G hLET H = H+1 rLET J = J+1 |NEXT L FOR X = 1 TO 100000 NEXT X PRINT GOTO 250 STOP ******************************* * the following routines are the only ones that need * * to be changed for a different i/o environment. * ****************************************************** * * ===== output character to the console (port 1) from register d0 * (preserves all registers.) * *outchr btst #1,$10040 is port 1 ready for a character? * beq outchr if not, wait for it * move.b d0,$10042 out it goes. * rts outchr: movem.l d0-d1/a0,-(a7) exg d0,d1 moveq #4,d0 trap #3 movem.l (a7)+,d0-d1/a0 rts * * ===== input a character from the console into register d0 (or * return zero status if there's no character available). * *inchr btst #0,$10040 is character ready? * beq incret if not, return zero status * move.b $10042,d0 else get the character * and.b #$7f,d0 zero out the high bit *incret rts inchr: move.l a0,-(a7) moveq #2,d0 trap #3 tst d0 beq.b incret moveq #3,d0 trap #3 incret: move.l (a7)+,a0 rts * * ===== output character to the host as68 -l -p $1.s >$1.prn lo68 -t500 -o $1.68k $1.o era $1.o ddt $1.68k (port 2) from register d0 * (preserves all registers.) * auxout: btst #1,$10041 is port 2 ready for a character? beq auxout if not, wait for it move.b d0,$10043 out it goes. rts * * ===== input a character from the host into register d0 (or * return zero status if there's no character available). * auxin: btst #0,$10041 is character ready? beq axiret if not, return zero status move.b $10043,d0 else get the character and.b #$7f,d0 zero out the high bit axiret: rts * * ===== return to the resident monitor, operating system, etc. * *byebye move.b #228,d7 return to tutor * trap #14 byebye: clr d0 trap #2 initmsg: .dc.b esc,"EGordo's MC68000 Tiny Basic, v1.0",cr,lf,lf,0 okmsg: .dc.b cr,lf,'ok',cr,lf,0 howmsg: .dc.b 'how?',cr,lf,0 whtmsg: .dc.b 'what?',cr,lf,0 srymsg: .dc.b 'sorry.' clmsg: .dc.b cr,lf,0 .even lstrom = * end of possible rom area * * internal variables follow: * basepag: .ds.l 1 cp/m-68k base-page addr ranpnt: .dc.l start random number pointer 0123456789:;<=>?@ABCDEFGHIJKL