IMD 1.16: 8/06/2007 8:21:04 1!"̀)À>A Not a SYSTEM Diskette (01!"̀)À>A Not a SYSTEM Diskette (0UPDATE LBRmUSER-RSPAQM USPOP BQS1 USQ COMUSQB MACUSQBASE AQMUSQFST18LBR!USRDFLT2CQPN !"#UTILV LBR$%&'()*+,-./0123UTILV LBR456789:;<=>?@ABCUTILV LBRDEFGHIJKLMNOPQRSUTILV LBRTUVWXYZ[\]^_`abcUTILV LBR defghijklmnopqrsUTILV LBR YtuvwxyVIXLABL1LBRPz{|}~VMM LBRVMM LBR<WAIT0 COMWAIT1 COMWAIT2 COMWAIT3 COMWAIT4 COMWAIT5 COMWAIT6 COMWALLCHRTAQMWARSHIPSLBRWEATHER BQS*WEATHER DQCWEATHER LBR/WHATS-BMLBRY-PUBDOM 066 tp_ws~MILEAGE LQG PRINTME 1QT FSERVICE LQGSVEHICLE RQGb :ߤN%>oEx0^sryM#ѵp!}&z4'a% \vMILEAGE.LOGJ o !"#$%&'()*+,-./01234:56789:;_E <=>?@ABCDE9FGHInw /Obzâz'<%=M:$;QBG;ښ$4)qGRhk L_Pl-swm /Po4^ԇRJI!Eryt(u;m ocjJ{MIAvcly挶5T#j~SRH6Չp1QYC;`sDcG[&Q %şGbXㄋblu &y8|c73KB 0'hY(GTѝ*xc,0\xr#Xw+)~O|Ok%ï 1Nc+kTWM )RKٛ m)ITC_Z)x_JB27xJ!Ŏ&+ϰtAJ}Ȧ+2wWf ~~]FJ}(R$GglRg3P\=*ߔd7Jgh[C;ٍ=))渚 7%m[z5T6wM$=v5YIhPR[J{4j,U1N(fYw<[nRgȇ+?v/+uGć_2ѝ*~8VOF5p?}ޤ"ɠݖ"D5TE )^BG;ښ$4)qGRhk L_Pl-swm /Po4^ԇRJI!Eryt(u;m ocjJ{MIAvcly挶5T#j~SRH6Չp1QYC;`sDcG[&Q %şGbXㄋblu &y8|c73KB 0'hY(GTѝ*xc,0\xr#Xw+)~O|Ok%ï 1Nc+kTWM )RKٛ m)ITC_W)??v?@ABro Q CDEFGHIJKLMNOPQRSTUVS : ,WXYZ[\]^_`abcdefghijkl-1&\F kҔ7`4lmpNy"aIF n&qղҔ7f1tW|dWfpNyfk8hX 7`Zfnƈp 26Gh4A $5wY14Vi8O0aղF7ZiJٿ}5 S;#:I"Gf+ܞ*OWu4QҠu+6M \pްtm-Hm7JҔ7 (8bY_"M+d4pNyÖ4hFiFaW47,V%ˮEtUfKSҔtW8=FjQ:9eߘ'7q6vn[H6UBUQ*̓n2[Vב]f$[( ]F]ܞ>qW6tUO ; m)DױMlzozo6BRF]{UsNycW!F}t<9o*&}LBQ<)ij..&~Na#0YvYX;l" '>$x0V]TabZ%& 2&꼱ea| 0gf daea| ̦6DԢG ycsHb"z$Lj6EjQ >Tx_! k]TAذHj L+q6+Hk gLx=Bj'$8mko"lUs6lPB{>*LwG9s\ jWhr(4#g퀻MRp6u^S _(pg^}T͌{@p(ghr;CzsBEjlA#uv[nzAB-D+(GJq+(W;+9mnopqrstuvwxyz{|}~30V86M>N2Eu]YOLI?7'UKJA<4/*(hSW47,Vśtm-al_ϣeN 6]/IE5lqވso"ɜh&`#%vbd6mV;R2a<- ZvmEM/=U]fQ-ik0C8M&v#IṂeNc;%6IYt#)S4}40? qnS7qE8M+B琜 :|iK!GDԦ=>Dpgv!Kq }}A\E u=gl5/c%#g *$fyV,Q*!4#wr YԹXxMMZBыh D|&U{Mau pE;5}lWHA>t| Qsχ1Pp"n |0udMyl v>UQsW(Rh:C]s:CR<9[X\jbGy r;-ᐞ܇tGH-::CƐcT k;hrϣ@>fRsVtdA g>6I x)+BK\xBw >k6yN[ ZB>R-' Qh|H|F@Plœܥ&Bl AfŅӖGKG0-׾B.+r{\pr« rn;R krIKkw i*L gKAn!=C..I%rY9pɊϽ}rjCr^' )IzN+4\/Miʯ'$qSO4hh0`Gh;> }6|8V,:-1`GpFMr(v h2cC ֹ{ V49䊻/=kU 傳1>Lb"Q4]O:;hro_}UɵlcSFiq o]iExl>VM??Et&0O$HV4d>8jϡjar6=M!{:-44yamJS;AxԆױvQ5Q0[e_ҔkqMV8jO<4) Zg5:D w MSR'0"؂H 9'Wx'v傻װW 6}\EP؇C;`ǐs)8Z˶Li )" GEA g>D< T*r֮ ";]¼{`KxRC.. wtvōw߇IMpO-Q5m}ԹقtG :4B*'`4jɓ$}3 l{jRBq@fk- Ij.Q8ܽv{6VcTMGi¾c8bJSΒ1>n! G&I}<9ɖ ) GHwM-M\sbFu{41 LJ`H>dUCVu&[B1Nk{Sw!cF=jL_BgY(-!Nry"`1PcU#Pz і€ Xፐ3)1dYEs)|BLsqƨ!'_tG'h" q@fk-HN_4BՈ=M_phdK u\\(0W`K6ӾB.ഥ,PC..pMz3 xs| 'G#dG!6}("0Ζ&RxҥRA' LD(G;R;{C"4L;`Br|fk-!Q5fc0"ddžܽMeiJS@Fň4ba35 "ҳ;p(܁#>*r-!_< { USkRJERB=#>ɵiм,@n !g!r`m8USB Bt|4 ڇtG`|rGA#۾mB8TZ /5uy^,`G*Dd:xWP5۽9[ kK0wX(۽9 |hɖjxGaB{$>DCvJ@:>xV,p:=2M@: ASt܅u)$ܣ~iJYדY"Թug> .YĐ;ܽ h鞀C>Y5ܣD w0`GroMXAiKGF;w/4hu=J]][mI'ٽ.I4A,Tw6IvrR@ǷddžT7&/Mi:;Ь pȣ\.D6bPA_Ҡuf]A" ԥh2 y`M X19[T4:&I:*݂,:?-Mi:ȣ|M_{h%3 wzB.U+`K-dUdK<|WAЃwLl;{ WRQ5" 8&rг2 I퀹B. _ҠuvɎWhrw:&E.8s;`c/d4R.UT B Hu.8swLl16}4Y V,}TM!BzN4) ZFi4èSAҔ@jVYXŶq Pa*$[֒*aS!i:-DOmnF]mdvhŸ4_< { 4&.gc4 k(^ݵN Ν;cӇ|=yLJϤ+;!_ASiAՈ;hֲ 4'2Y-R/MiJS~ٽmٽh=3 {K) ZfW'qF<ZF<Zi2ImbQnZ70֟'av4AtӰovY&i? S~$m'aZ; O!Zm'Zl'^i2MsoDh}ݟ)Zl'aZFذɡ7C>^g+ Zkџ)ZlZl^i2~C뙇IWLF?zFh=? Ҡezi7C뙇}-z=ozh=Jz=m7z=m7zҠe^gz7ZOn7zҠeiӽ^{^i27i^ol7zҠe^o7z=q-v?zzaCҠenl^ozAܸO{Ҕ&⤁{__=~4h5XMLcfpN ;x7@i:Bk&L4$!^w&:+ ZgA,( r9C nޤ%1Sv!CnzCմ68+\MWQlӣ1`Gڇ|=TM[ꅏ!p|u8#kMq>ƀK&Zj -;RpVx#lDÑmC.. Qs)8s@\#\ș}y4IsDc?iՒ'ѵI$6*iD.889ښMxUnY4A, ;&Ǹ4V6T!<ƀaȝ =%-MEMTq*&? iF`M[ CV!GD# Hw 3Qh|MB)*r+8Q.h0^A&[jH-g;VKqC.>U8]{>ܣ-gv!\Tz֥+<; |+hNѮƐH+65ϥP8>FSi,#Y7O r|h0-:# @|=h# H'gcvp*Lt 3Qpȣ\U`Bw\&:IoKa/cFw ZBIfDp{MA\GЋ"i4YwRۍTZP)*Ha6͢Z$6I 80 H9>f+ qȣ\Hw wŠ[>zk;s}T oΥ Myl؁|ԥ oG}\TazjPHcc&:`Ǹ{pwā< G}h0-: jtGI16.8D@KTHw4UA/ <:f+v݅> MwAո{p3ԁtvPҠuM#DG8 ٧ XEp}8^č16} Pd*& Y56Vb M*rã+-1WTazUd-dGhrC>4U݊b"3a<+Ho)%y b&)|1l&|@-O\C..P5;B~iJ֯z"L8jIvIF'PҠuֵiՒ'6IĐ{X;sMQM^Ps5T(=:w^S=lp{ ] l*l$a-6/-XaP56wᰶv TaZt0`Ge;pF# @|6>ƩȜ H|[H&[bFz~=\a^p IkkOl"AlohV/B-dKH/#\p6-۵I'-T:A#lo@ZM@: ASt܅u)$ܣ~iJYדY"Թuv&SERVICE.LOGZ  !"#$%&'()*+,-./01234o_56789:;<=>?@ABCDEFGHIJKL;MNOPQRSTUVV:83-,+WXY&/B*:X3S,Muq;3(H]Gbe4rKV(/D#{Rđ S^+*kjojiCH]G t)cdV?HlbiCHnI*3DҎWx]zJH8E3b&6n RP$(=#/20sFvcd 3 'P*:'jyOwuyEѠQ-ƻ>B(ՔopQΛ\&UgnGA#TMEveGal:w^CHwMB<7X( <ƀAj_!3^Cy-IK0`R-BzB)) =gO)4;Bpt[ ƐAצYTKD&cAt81`ĠtOP5\- X` 6A/KSD:FcMҠL 㰜KAulHWM@FzsrJo+l#HҠm&]|z s_lo(Mi: 1`GG gܽ:o6y^x;Urv+2}P5u!!hKAz̽0Ww Ykr]ȝ*0WQ5 AK:9ܽ uQlӣvv}rkH!G}B1CVx#xTNyAUҖwsq&-1m8!KovybKA#x;.{Àƨ@MropVh&3s%\z) ZYX;l'̦O4h_`4%f#T45I 4i USle;;ܽ:w,Kv!l&߁Q5" GEQΝ-8{# h:c̥f4I;KT_(UhYMOܽQsWдRp6FT4[kܣ; Ӣ6Ν;BAxcS"`W>~Ԣ&鎠´耍\uY(GՈnj{> G}4GHwMEl `" V,<9ҍS0YxxFi|fk-=Lkw mr1=TP@P'9B 6Ŗ "(Q5MylH#Gm0jq=h$}<ؘ֛USbXPPM~>ǻ>Bǩ()_"hP]]zA5\o50<'6rT`FGީny x'4&N32 SN@=uV/EY m[B hKCo}]g@m~;}mݜ~7OM'S5# _D8HZ^9;b * 2N}4n Se[9-~Q!~.ˢ(c>m9ke=F\OM'0n STˎ x'7b-3Ky %exMb2j7BzUկE5ϯ_6^zq+wK]zJ[zN-Ud*>6J."i)HBw RMl, {Q_(PbX}AZR)xe]*29}jX $X@-! ؓ"XP]S{WpM(BG: KOiG#CxEb{M(BvKR& vo dh #SF)̟3'6qH"Fi|f0#c|fny`@=R8WΛ|c?/Ujq5M@q|;rޔеd4jƂ2j7({]9M@u?@ABCDEFGHIJKoLMNOPQٌ$Sb|rnY>{3|ٌ?}_VB %bYS\Mr6;q Q^=\:rw/pݢ'ALdӊ<k 34F؄ 8k@Uhg3>F)q +>{tG-zf\ql ޒ uc y"Q8ĥqԄ>8.Ix{6&06!)F5F?|q;α#O WULAq2lv4p M&x 2Pv6;;BL< GqiLY9o+[H(g68JӡСWQ#g?4:4z@d<5rVG@W>d!gzbS'CW?dOlUh!gG thp)@>px,ZQY1&V3mt r x:B1᝕3y:4 SGSb,ZQYt _c$ZucbŘB2Y{~g Z;%v6;[СS\MѬl .rf"lv6U3>ū?rc)Sl'wnq$8X&@K\b:9 ~K,l#D b8DxqK x^vf`f(<)ny`^BK()(o(%8TS<~-2 ϯqUx~\U5>^6ЋX]Su2n S( ƵQt?OOABNJlbc'Tˎ:E"/+\ bՒO+ ]RW̉MW+"*?6W|MFa"݂ R{(M.v1;VEHICLE.REGC o !"#$%&'()*+,-./0123456789:;<=>?@AB"՛_Ͽ=B.u (V)W埐ThoxᒃAv r(NC%]1SNEMyeADC 5#W0BS^F(c 8TC4mr(ӎ'b#HN1p:cj1^?{_Cm58OG;mҎx[v1L_yH rcAD3Dآ5#[]pg-SNYXot Y[ot yD4LD卮F2E(%;Q>aϝ.*K7:,b7s6 JjFa Q^7Arqʩ҇fi,'PW$O3Gc#Ntb:XjqVӏvzi/={cۿN99f"EkF$["]L)aSO~,l ͓G#h%LMBt^ WM0Pp<N]hu9@^sS ϗ@QN(A} g \&'('*΂8Ⱦ&v@2NYYȄ:g dS9n>čY9)2΂8R:9؄NШVMRζr#\Y <{t?}|h,#|ȝDJX(<9 W9*΂80&g tr/p;; ^ /~Kq9cBi齳ٌOb xh&Zp)ZOfgC].C]И0G* wYfg3ΑYv1+a qڱ ,1.fgH_> Uvj-r$Z@&>@F v6;ݣ[6&yT(`j z쬰 O?K,QAaSO΂?B y$8И}x+Z_(ًqX\8=I q\ Y΄7lph559;\z~KShJ|n8j¹lū`5Zɷ@fgre*b<@ ū>0Tf|r G5lv [ӡP#C]r d'CFB5UE7 y%F9ްaVBンPM)xgAAalE(;QBybdŢuFgr7'BxHc©8 }P&Aγ#+6΂Lb6B"]GQq!女P#YXٌ)xp¢:v2vaSO~HQ)8 }PȊRıQ#*,~ouq)lv6׉ g 8 c'_#h& ]Ne QN9u;Jvʩ|ž;]T dKot Xt8 nN9N#4mA.8Ԍ\yMyeA o8S X$OȡL;"Hg 983G錩tz]n_ =÷<툷K;mҎ_z0rj #-ȍ-:_sD4rc׌luI>DN9eykc)fm)` GLD3A76LArvSG=w:,ɖqܜrjϝ.*Fh+"*]p6DA{p)Jl#HCv\E|lrFzSzS f"<,otm7:).D9(?Fi|f0#c|fny`@=R8WΛ|c?/Ujq5M@q|;rޔеd4jƂ2j7({]9M)r4%>75ổQ΄c$ZH?8I7 DDShJ|n8jªv*!OlƘB2aBk2 1'ȱӃY(}湘И \,t uB" 1Fv40I#; sFRd,80x$cd\h@fg3#1yFj-$o y2< y"3a f%I>7C94r6cj}r"v^fJ#ȣa\)ə8cqF揻DS >3JlFL߫&g:BxUh!q䙸NZ_(8 !#)oj-a$Zq 4 U@~a S&$b8BLLue7YFh ǪIP}@넩܇8 0׉̆o !$!Hl>  Ipa/$={!+%`-Z.*)$%p e(zjA)TE ).zD`SB #d ${RGHJ %rk.hs_t"duU`y8B"]]Txjz*U18D]hr ,*"z`yz$}maBkM|BǐEJ`HĬAz9X dhބ " WD&}O $j#`-ZJU )QZBWq(+݊Xc"!*T &bd1!ܑYtaG f%.{0 ^t8(0С0ylBS gqp]70ț)&gA,BL<; ՔWqrK[:'g^]@":A6D;zbS'䉰j-,TS ,^Yxt@^DDfm'y"4RcDlYzu >oBEqB:d\8 uD@ׯ_+Aa[HB v6;q1Pk$bVr6;e@@ {͛=6Ía/~Y{Q` -$g!;͸M(5v1+9]^_΂_MLit improves things. 't find MDJ*e}m"_==BkM|BǐEJ`HĬAZR?AJ ӈ40/LJ*Epdӑ2 1ϊhD}0 WeE *L$aZ 3 TbDERJXUϊT*|!MMHM:ܻ$u4w޵G0,#jlE:U !yx'ϋhvþ av&3 EKZ¾$M~!+,쑈*G VYدGtN?#d0bK"  X tV^7<쑈^+5HoF"4еnMJ Tu"4igC)2c@̊CKjD^4;:bVgN&bǦрX8Ec40Q>(Y-JFܢ6Q>ڊ#7h|nQ m-J|nQj(Imő~i4 Z6%ܢD0ACX:9vc# daWX (߉Sa4%j## &&ϥрXhcV[Ҙ`Fc.>40Q>$v\ u4Csv G"Wh|.+H-\ u4CK9Wڊ#wr*DKl( R|.+Ht>9yk (,N>!ш+ -'$KKR'1%>!ѩh@Ķ%6Q>!K}F^%;k;eY؃>$ >I8]cy<+9m@^G.Y/uX.&4qaz:":LZM噡 UJ1{OJݗ>Ml#$JIdQ ћcn~?A:?id v47!YvTUSPOP.BAS  !"#$%&'()*+,-./0123n456789:;<=>?@ABCDEFGHIJKLMNOPt0w QRSTUVWXYZ[\]^_`abcdefghijklmnopqr z{v ostuvwxyz{|}~}/rp|1qx~y]&Fi[TI<8"smb_7(uke`\YXURMLHDB@;-,+*'jga^VQPONKE>9432%$ lhfdcZWSJGCA?=:65.)¾6Mé/@x.JÝs#* j袢 dop#7%YhS5WNɪzJ1dU|,yO*49 >ͥX~GX)8C>X6 PT!|3 =Rg(&DUFOayߑ;VʳϖW/`+>vV[z@rqpq֬2֬ayMMHy7RGi~1Mʏ@4mHC ]hAd+/l-! 4UY.v䎕s.[fk֬1`5k5,?dfh ^QǕrSyLi6 :*Bn*?dZ$u;_'^Mcvo'~ Z閉7p#7%;rS m$iATFi@3צ@J {OM;y.c@!pE\AE>]9q bKvĔtF%%aZt!{ŶO' |~'M>t=jE9hl% :vB tVH׏<#" >\7vll\RQEϸ.Ls0 }4;v,<ɢ(ǣUdq-%%J"*CEEeؐlhPeQQ]FA-T]TT1Gbt؜^G}ZL0<O鍱LzQda;c>2$-tz<}:n#(7iym7 6,|h >aSlm>2DqڸDAJ ._lE%PD^%;k{}d%Ada?@JCHOOȠ[D>]S,*"zВRAY[32q] Աct>\0QCMp˓}3xW36rfPaDtN)l6tJfsTfJYu°F^ :ptA9Y]zDE?Si!H?ЀhmCK6Q^V{!'2t7L<G(upo`8<,gT|]  5S쬣MOo:a_'qs MJ;٧7OՑ) aBYKu:cs MJЙ^0baYр) Y ܼ@nER{r0ðțɡoJM,6fX.flf&u¬&_cMse1kCCkc9E?,MZJra/N)e:fQ5!?,U̗delYqabz2"Y̗be~,;5?, Ա0CA-T]TTtERt EӬUK\Xf,ָ'Ͱꔹ;f)qao*,ָLO(1YnWjX2_5a|t5?,U,ra2k$)sBY ֪\XfV2_4gt 3ugCE=PDUx.#U' =\FN\,LYL68P7Y-6yqj$o:N5G|`c㺈N@=)A.w |[Ƞ[D#>;LJ 6-Goq)TQ 0ɢ({ƹwKyz{Ggx% [D9>?>2JQ `OJQ Yt̿h`ҺnQZмRgT"}&dyhK2@'Ýs "8C8tYO<]:>`+>0D;9GGhF:":LYGD! (Ξ@ϴ}`'JԞP pp)\j3opAz{w>C)`KGBbnn.47!u2 <%t5AG]M&H -G% - "ő؛M]2da7t3LTE=QIrH-8aO48t͖h@hqc7g\9( U@===YHq#r- pp.8n؇ƍA (Nں1 3 *zԞP =}q"ݰӝq貍рb%認4EgZ7Qas6q ((8\q]0CA-T]TT6 6-Y5Os^Qm#ät7L<G(upo`8<,gT|]  5S쬣MOo:a_'qs MJ;٧7OՑ) aBYKu:cs MJЙ^0baYр) Y ܼ@nER{r0ðțɡoJM,6fX.flf&u¬&_cMse1kCCkc9E?,MZJra/N)e:fQ5!?,U̗delYqabz2"Y̗be~,;5?, Ա0CA-T]TTtERt EӬUK\Xf,ָ'Ͱꔹ;f)qao*,ָLO(1YnWjX2_5a|t5?,U,ra2k$)sBY ֪\XfV2_4gt 3ugCE=PDUx.#U' =\FN\,LYL68P7Y-6yqj$o:N2  *!6x :ʗ2_!6~#a{_:> : _!l2 <2m]"!"!X =:Q P  Output drive = :P2@ :_͋"*"*~ #pwb"*}š No file(s) found.*""* |g}o|g}o%| Out of memory. Use more specific filenames.*" $$.""* "!X  6 !Gxwgʯ#Ò!"=!PD :2D!PQ6D< No directory space. Aborting."K Files has illegal decode size. Aborting.P "|rs#r#s#r#*+N!‰_iu*͆D<µ Close failed...g  ERROR - Checksum error in file 1P :—1~#_l getw ;get cksum, and store shld filecrc usq2: call get1 jnz erext ora a jnz usq2 usq3a: call getw shld numvals lxi d,258 call cmpdehl jc usq3b call errext db 13,10,'File has illegal decode size. Aborting.',0 ; usq3b: lxi d,table usq4: shld max mov a,h ora l jz usq5 push d call getw pop d xchg mov m,e inx h mov m,d inx h push h call getw xchg pop h mov m,e inx h mov m,d inx h xchg lhld max dcx h jmp usq4 ; usq5: lxi h,0 usq6: push h call getnxt pop h jnz usq8 mov e,a mvi d,0 dad d push h push psw LHLD nextadr ; PT TO LOAD ADDRESS LDA topram ; CHECK AGAINST END PAGE OF TPA CMP H ; IF AT SAME PAGE, YES jnz nofull ;buffer is not full yet call bufull ;buffer full, process buffer lxi h,buff ;reset buffer pointer nofull: pop psw mov m,a inx h shld nextadr pop h jmp usq6 ; usq8: xchg lhld filecrc call cmpdehl usq9: rz call print db 13,10,'ERROR - Checksum error in file ',0 jmp erext |}~# **,~#"*""X* 5"*>O**}q#"͆yi**D¼*ڒ*" Disk full. Aborting.go  Premature EOF on file... aborted.g:!=2:C>C4>==2:2:O:\O>=2yO!P k##^#VzJy2z>ʈ{/:Pʞ_P<º: _=!_#:P ~#P<ºì: G: < x@>:!~ # >.!%~ 5# *!P*Y@G:a:  ~# x; errext: pop h mov a,m ora a jz erext inx h push h call cout jmp errext ; cmpdehl: mov a,h cmp d rnz mov a,l cmp e ret ; get1: lhld eob xchg lhld sob call cmpdehl jz get1r mov a,m inx h shld sob cmp a ret ; get1r: lhld lastmem shld sob shld eob get1r1: push h xchg mvi c,26 call bdos lxi d,fcb mvi c,20 call bdos pop h ora a jnz get1r2 lxi d,128 dad d xchg lhld endmem call cmpdehl xchg jnc get1r1 get1r2: shld eob xchg lhld sob call cmpdehl jnz get1 mvi a,255 ora a ret ; getw: call get1 jnz badr push psw call get1 jnz badr mov h,a pop psw mov l,a ret ; badr: call print db 13,10,'Premature EOF on file... aborted.',0 jmp 0 ; getnxt: lda rcnt ;see if in the middle of ora a ;repeat sequence... jz getn7 dcr a sta rcnt lda last cmp a ret getn7: call getn4 cpi dle jnz getn5 call getn4 ora a jnz getn6 mvi a,dle ;dle is encoded as dle,0 cmp a ret getn6: dcr a******************************************************* * USQ support code * * 10/12/83 by Dave Rand * ******************************************************* ; ; Changes made by S. Kluger to allow use under SYSLIB. ; The following SYSLIB routines are used: ; extrn bdos ;BDOS call routine extrn print ;In place of ILPRT extrn cout ;Character out routine ; ; The following labels must be defined in the calling program: ; extrn fcb ;file control block addr extrn buff ;ram buffer start extrn topram ;end of buffer (hi byte only) extrn erext ;error exit routine extrn table ;pointer to 1032 bytes extrn bufull ;called when buffer full ;(this routine processes the filled ; buffer and then returns for more.) ; public usq ;unsqueeze entry point ; eof: equ 1ah dle: equ 090h ; ;this is start of baseline USQ code ; usq: xra a ;force init char read sta numlft sta rcnt ;and zero repeats lhld lastmem shld sob shld eob call getw usq1: cal dcr a sta rcnt lda last cmp a ret getn5: sta last cmp a ret ; getn4: lxi d,0 ;pointer @ sot lda char mov c,a getn1: lda numlft ora a jnz getn2 push d call get1 jnz badr pop d mov c,a mvi a,8 getn2: dcr a sta numlft mov a,c rrc mov c,a lxi h,table jnc getn3 inx h inx h ;add 2 to point to right node getn3: dad d dad d dad d dad d ;ok.. pointing close to right plc.. mov e,m inx h mov d,m mov a,d ani 128 jz getn1 mov a,c sta char mov a,d cpi 254 ;is special eof? mvi a,eof jz geteof ;yup mov a,e cma cmp a ret ; geteof: pop h ora a ret ; ;end of baseline USQ code ; lastmem:dw 80h endmem: dw 80h+127 sob: dw 80h eob: dw 80h ; nextadr:dw buff numlft: ds 1 rcnt: ds 1 filecrc:ds 2 last: ds 1 char: ds 1 numvals:ds 2 max: ds 2  sta rcnt lda last cmp a ret getn7: cal/sql׺T\f/\IEp:c1!Äl |I  d˄z&xLnG1ŦL(}„S:c0Ub[&Do`pJgbg&c`*NRA3ʄz&xLyG( x&dkKL`&[&0eŦ';5P-Ja2Lv.v>vɊws9Z&h0(x&xD (6vh0HC2!zÄS:cn"0UbL83V<#0#fЎinvaAN -a Z?@ABoCDEFGHIJKLMo^cz~ xŽ wq#>wOQ'^|q/~};ivIdL>ww/FFgT!1Y7Exۥrw`$/nv XӏU`$Lwz5E\܇>=c,'8X`~_7ŊwqvIf=⦨o4:5hvm֭L]lWjF8zv X0NŕV3!x&b}:L0{:Lx X`cMfIɭ4wέϭLX`wt8. d>U%+G7n}n%3AaTU Jr0M42ŗ7[|l>YUԩJ`‹/[iL VI΋|n޵w jW0 0)_8I?w}e$N;2`*SP!?ifmxVE$\Af!_v,}ץκRw^L`Bih:Y&dkKlRpgy&& j@+r+Q(iȗÎbT1Q+6gRpF/LUN4͎bT1=0/eB tƐ/7LC<2;Q( j@hf.vQEi}L8 heB1eL+u{Sqdשh)1Y5zۥve|yХCجYU|y#W hfaBG2!ze!_0rE`B12=RG&xDۄ ]ZPm L҂ʄ~ Ũb{˄ԑ }Qm&tiAeBG-0K *RG&hՀf&2z if]:4+*Q(6- }QpJg -!aB;vە &CL\[&S$Y ݫgGçӧ3Ӈ{?<3_ݳWW݇3woL83RU`^iRnTsL(F0 $Mza3Au[if/Y[i%+)iP}eBG0K *rՀ$53=*Nǐ/f!_XJUN„bTQZ*Ӑ/g&w2!8<O>~rq䀹oyhNuM{]pj=bf&^=*Zzís1n:֚0såͭ\>Q2f\!a"_(9R07!a"[]*[ #"[\͎< ,åSå!Y ! ~v ,4¥lͭ*@"!@!,~(.(w#!6$@ͷ͎͎< Bå88>>,^,V,z  ! ͌͌z FN#~#!!!! G6,q,p,( y/,w,,,(F7$>P!P+B ͼ@  !@͎\͎ѷ33: :(ͭ٧OR%D\͎\͎*_+"_|¸{P͎͎ 2͎͎ ͭ{ ͎ Î88 (Oɷ( =Gy>O_0yw,$o>}.\!P > FU Fast Unsqueezer v1.8$Input file not found.$File open error.$Too many matching files.$----> $Out of memory '"L| ڡS^VnC0qJrntf,_VCgDO3YV `g]Đ0%;:2JlP^Pebg \j!9A9r2)er`g] 0BB^^?0CvW*";+jU7wVB;*Q( HN_bHx~=yN,9YUꌌC,_ *͠SV큹RPKTQMS?Ba$d>iJL(եr8^w_,z.$Not a squeezed file.$Checksum error detected.$Program requires Z80 uP.$Output error, program aborted.$ $ "[!"]͎8͎(8*]*[ƀO w# "[*]#"]v;FU18.MAC`  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMoNOPQRSTUVWXYZ[\]^_71o߿Ő1o~k?UDo237fn/Rgeml[ /o1oxogڙ WdVƕ0LY-k+rxcܔl/7_CM 1dݿa5B\Mi7dݿVN"0r%TΪ5.soVobǜƛvl%Q!tM W7/C <'u~o\y:ʙ재U@rBI^3C3¥l>A]Q P+e v%e$BgdՑ/tFMŐJm` ! HN#:#cJ@3B<''1$x vJE*OxZBﱴUMxPvF.C&Cv~w1n͗/?ĐsΪ5P9"zK^+-%r,2-1$tVͬC{HNPVϴ3nBau;\Z9x=t1$b ș SB-Pj5 ƕȴ=0 cH2 3Rg9FD FtmlJ\Z-BXr!T<'(Ȓ SK"ɵG-YWBINǐiZ<*?Uc\ RY\{XU&wD%-O>kLPX50( ULU%xZ TBP/001$Ԫ謚Y3xtU̕љftPue=0dl ǿVCg,/ƕƖV%"rnL2 $'ԕ##!q 퐑I!Ősuj,pEvTd(TKzCD+g Z91Q 9RBgqCBI*jf0e^vhPv?*/0SuEoBg!a]M:T3rduP9"jf0b)Ϊ5= r=˳(t |5 9cHdT%>CquC,TV\g_fE+1zYOa0hj8*`O+!A/Pt`ZYxuE%jU.s-Rv3Y5#C!fq/?Đl:7nF) fxL,]T3d$',ϛ5 e@LkG_͢ Ou;ԙNBrɄ} L{!<7CG^9BBA9H>0(KG#8l'Isجԏ-x_ h|t&1$W_-(HN{3#XUv`iPWTމ5TYa1$OcLyV 0RJ:#|U=} U@rB7#c ArBU@UWTʍbH0WV%lwD%`AĚTQ=y=pEkbHZ9΍ ^_J0,Pt`Z=&*Sd0Yj#Ke6[*_BYPR!d+^+ZUY e6BP.[@r3 rGTRɅ1$HN(tFv3TR!ŐsΪ5.iF%qxb~Y#5^= 1$L3{0*c +#( k7e JxO4#Cօ1$~oZX"7%;!ݿC V%>UFk1'lZBY^΋jCd=>A*#ca5_-b!LYZ2B>xkmcNh0U&(tF2L3U?ж?_sBK2A0)KK0>>p/1'|4vT)%cX5s²ݬANSI 1$,Ejʁ>UFq5_W?1'v/VDVΫb7MG(qY LyB3_M=O 5PbX9aED3­O9&<|ͯn>Z-Bg[O*rMvkk~9< Q ~>L|ͯ>0'I>L`Ғ1ob?WįOVb4z~gc-k+rxcܔ 7_n.<_5Y %?SBa,uVUM% eᔻ*t]k#Z9C d5'߷;愭v%T%^>EffOږ' s¤,vQ}_؏^>`N8e[uEݿ|~7- U3kXTiK/_&=Я'oz愓r/_'tV;A3\ C'nZ4zn>r\$'f /4N(tFpfx so*LBЮԵ WB(tF ^dޟ K˜$7AVT#??cNT?P /wR_iC^yn K˜ժrBih } (tF :7**vϧ1_0'L\ j ɍS ɼ92'*!>p=ժrB  蝐Z9LBUIWI rϷh N{z'VӅ%YvZifhj- 9?@$'JJ/1p^7-_6ן8a~^q?7G愉+Q+'UCa2'nZ5wg~ LMd!9-YK-9  ec?KE+dY ܴz믜TBggǓ|3'v ș j(nZnf;^2'l**vǣ~5Y e] JBg]@ cixn֓ ߾}rΪd] ܴ<=L gH(Of=OcW|z9z|/NE\:1nZnQZbN8luFP9bGN擆9%bHx.ڒM;_6`"{ih7jbZrCeF-fhsBk@< LBS%$'O_*(|t!ZO=yN`bH$T v&Ck}zBCYLU%1$Zrv3`po9 #7R 6mߞOysz&9Q 3UW4ڋ* *hU`{` m3ڢV֒+=D-YLXr!!3"d! +T`PƚZȎpIb* cCT GWePEcqOVsNX Sԏ1pdtl7_8aI ^rYnw_7p{vuV+ e!9a<>W|͎S ܴfI ȩjcA~?' smad k!П6ovOܴffÜc:OM7-ݎ *A3~VB9j+iG1pd3f5{ ܴ|n_7wI ܴv;^2'vQպTM˻f=-[NP茜Ӫ(Is/ZK%]gM˷Yߍv 'UÔ,THk7C31}W+7$P@ k~0ym֜0Ω~. Ja0nHk7C319ax} zŧh<%iy׌v oH@VEA6nZ]^ohpšUiUd)l bH%ʂL% Q 1^̷扛~n_708hUx;nx>Ƽkb=9A]:#gv2SS ܴvu'M/vdNgdT%]%(i |yMm?) OQpNP茜(-QM˷qiGvǣͱ?Iݬ'?bi̓O/Gfs9ai bH1|W'nZnQZ0'gUBg\y_y;OR /Oܴ~Μp+#u bGN&bHXR,aAP9JNv1ɵ:erZC)Gn>`eF@Jv0РݼڣPvbH(BYHNJL3U S-b {|$HN'HNeʕ.bH茶\RGn 9aW&hst!h 1n U a=@Y޽Ż焃snEGBvdS%bHЂ$抠* G\"Cr#2YEօM-bHv3@r3Z ]F9`C e Y*Ua$'=T jJȢ@{tJ;! Q0NINpnԫ* Oª4* 9Եh]@;@PE N DwBYLBPEIY } z2YE*n`\ A:KS 7Z# SӅP ^kx%a S%UYdVECJŒF0DhW$'tV>C,R,[-TIEG#\GȣjǐpwTk\yBg >jeTƐpX!Őn]jf5y Mé=j N p~!R,[7߁.<é'C΋j=c'>/E+Ytd eHNTnՑ539(iG* ^#87|p{:0WrbN1$qӅNZt@^WUV"7WA;=T2r3ɡ .h;ON1N -ʕZr1prۏ&#'C <4 ?ɛ9a8Bgcwzu oH 9ZPT?jq%iv~NxCr7-yyN :Eg-+ ӅP g8Wnobf;^ᄳӂNi'd! ș JJ/cH1ys|i sVg@>΍1pdtkz#:H e л:A{HNd Wޫp:GNgQ1$^l Ar+2caI* 9=*e 6} T^(jy#BYHNLUhVh1LBC.s]4:SL!Ő<'PY.;bZr$'dJUI@,@Wd1$8U紀]] + 8Unv5ArA{RvC}Ewb?׫ \U LIѪߞVT,.srE zׅP U T]nBrB&+F8P( xʻ} sMV;Ur! ^O3B<'A;Pv2eJCq0]gUg•*q%,Iev&C?CdJ*`,*iy=n>OBkU 4t:Đ`Bف,j J*L^ wLBH  J*- 9ddʻ=p.:C0%HNȌY&Ӆǥ2L "p%!Z.<::LYZ~C xbǜp{qÌRJ\jajL+U93'KRYG.0'%:x(GHN(tF ~cNxCNq)LBw14&nZnG9a1]Af|s7-%RQePFbH 9!3^0qQy*G0F 9aN]B;HN Őp^Tꔃ%CaɵVUc-3'| vPdfx%s:ׅ@UK&T GIzJe ̜0ύ<CYϧ19ՏDQ)SBrv]%1pdԟݙUQť,hL҈#S <4 f3i9aE2%tG5yo<Ǯ_x9c!jUD#[(;@rB-qv#k$'L:#K3CS **A~"33?Ie3,ʹ>c ЮN3rdM>Vק'_`愭^m2 9dB!Xiy׌6-s®y6;(LiU@UUiacxt0.#7P$'t| ܿx XJJ/= :2"3>τՃ Xi/dm2ֈV)n1愳ӂ]3J9#BLB[/. O[*Qp~tpvZ[BSʌ( QxKVMQ˜0q%ӢM-AޒU ^b?&p zF([6Y 9&LjLB[/.1&Ss|ixiˆ9O[Akj!'M2'l**UIW UQ_ar>5G愉+a##8n=cb!eʔ]W UQ/Ik N 4i7*eCj J0-,+r]Č0T.#dfca7I'xr;niy9:/뗜(աV#L LrhM輼ΜTiUdqR mOܴ܏.B@]YKNP&OW3'OFm 1$LLYjʙ W&ӥ'HY P*ɣVUVB;HN.bH]xzx\AYx5\UY GWda*S~q,'!^_/;s¹#7]GΏ`h&~}xt?l9a"zK% >v +yHnU5UekBk,rhTލg>$/vBڕ<$*e@C{hEL 9ŐNa\ QRmx*! b fN8;-j y1N| ܴ kO% e]mi 'ͰkM˻f4޴ewN8;-5ϠSV̜b! 4LɎ 92Wᐓ)P`\ ,bZrR &d$'K-pAh2#t(.ӵ*qZ!$1:pD%ĔP,ciIneNx0 ^p{8!7YqTI1x40l^rNC 1$UekBȍ,r)vPB@~Qז=ZCBȍrS"jK9 z ?B.>OږwͨGBm,AH ܿx !n1=sBTZUNM˓QoVW|z9:mھ9rX9Ѯ"2Q zūs[v dNAT g<'zt!URZCؒ!7YqTIbx|MOܴ<|󮉁']sǜӅ:- HN(u-Z9c14]oVL0BYB锬v3h2nZ}pšEjIݬ'?S ܴv;^2']W e ܴ<I˜bixn֓ +2% ,ʖ1qsgNXe ig2} Y9aM[ ^T>^b!cNljU9!KTCQ`J(;-87|bHFr8HNp&êC;/E+!vs|ȜV0HNbGaRl|Ȝbv~uq +KPT?j@S*Gu?]W|z9:m0',-tWbv~us ~K)eN16_9aC 1$ 9Տ@* QP-T`SV 9Xlf"\rQ`,F(enCǥc}Mm?'9Տ@*j'MzgN1CRKCL&dG,T%]%{s(1 LB3rdPCU0٥YxL C2*px_ h= Q +#-N APpi<-PNC ~j*!ZK;uke j*)iUdX)KªZrNi'dqeF0e߷;WW xLbId4nf * OQL; ai0Ľ`2=sTMф9.#7,-yCa/ ksE/^0sRKCJNi'd} ܴ|kF#''+p;@u*)>0'haJZ2Lg9r̜,-~owh̜:#d*>0iv܍ )K;Bci s/9aiGW Nxϙ9a0YC cKFɊ{J* 9Aڙ WjE 1æ}/9aSBYjm2-젝TI1f˜(FP9"S ܴ<$ӅZ ]F9*b?9TQ+UM ܿx K-uQ( :149u\ U; !GTbJΓ*c]s70'+hOcnS |>aNXV<|e 3jw̜bU?gyn䙇ɲb!aQM~%QMSvvvZ45!ArPyf8aԏB%L]+[j7,ca}7'nZ^G3's&)KKWåLB1İyiM z/Gzմp.@{%FS+ L Ca9͟iy95w } 38z'.b!%ts]T%`eBA;n( 9!B1$ 2*dP^0 9 Xㄨ0fbHxKV,͠= 7vJ(t jJ-Z9ƐPnɍd$'Lxh f9TJTn=Q 9,jU eq?ɼ?yNP.[@rf0zǹBC; U&ͫ#H=rcHp TTK-#y$'ڙ jQ3KEcau̜R ,| <9Z-l jQC$'JJPb fNXY=~َ LyUIW Q ܴ<ͺǓeYO~Mm?j%sBR{JPbhl} <4 /z#& U,!yM˻ft{zXn] c51pamw]7-OFx&~}|{n8D(nZ^G]ϿqŠ(Kجԏ13s\a<>CGl 7cZ :boOܴz˜pvZ>L`B4***1>񉛖ǣu?o&&A0(HNbixn֓1zgNX+F`Ғ1prۏ69aQ$'JJPb<>Z-Ke <4 /z#ެx^jޯV1qsgN%a<f(n_^ -ՖrZUN/*.TbU?!p_7-;>jK ܼzBMѺxL)l ܴvdNTUx7-GWyϜj!$' Ou <4 /z#ެxœp"*!9A ry^jޯV1qsgNxCS |s˜pv5r}?]p (PQP-1pr?`N8%9Yē_B< tVs´* ǮA33y7PƚZzscM-dqZ91yHNnZ58_hOږ'I 0'<+Թ>Gs|v9owhOc5148n11^6?c ܴ|竻Ѯ#} ܴkFi~Oc51pxs}ߍvM 1|m17ק#_pzXn#_ŶYs7eUd[­v(tFYY[&Z9J\y )eYO~>^wkbŋxr;nx񮉁ǓeY͑wM |cq ܿx7G51qs䶏#/1pE 1>jMm??CVYFLVYj'0fF#X,ArbG.yi_O)nZ^G]ϿqŠ(KbGtJ;!/,2WS )~=y?q~k973­.TB;] ܴ2'lj'04[xT)nZzǓeYO~ nѮaN 9a ͌>UE+C:Oܴ<W| @N 8~ 䵥2~}eYO~Cš\:7B 9AUUiUdGRfJtVvbX/9a ,<*O% e**AgUMk7׫ f:2"33hOpuFzh0M-b+V9BGKGŎ9<Asc=$'X|Gu z/G~:9ai x7-G>$nQMvi%0٥Yx<u1x43''Qy/^0sԏ`2Xxϙ9C kXjU9*¥2j  =nOJ r$:S)Yq%ß.v{heȍXS $'(GC”`##Tú'>ƼdNX,_`:(tV.`iXʺ} 1CŠ:2"33\ҕV$ ue-9t!`= jU9*ǐ0[ @{jm2.s]8Oğ.v)+FrS ',q{i<$'x{ -P<.u&|Y)dP__*+Q*h] 1lOg%͠ HnӪ(Пikݞ&/ + L C 1$UBpNЙa*W@L]j7r%T fӪ(Ѫ$LYj7vq%ƕԒb1ϵǥ2LVAr!aJ3v3/>C·op{|-CbkZ1^o#<<2Xj/Bm H1$V@riFnfwPel ^aCi%Rg2]Z U 8ԪivŐXr%_e * ڻgK&ڈffcH ɵ{d .XUk?´HN hw+Cb}5tF UF(tF2U1ӌP.[caiˆ|۟ibarjq^\p{ǥuebHxNJ0,~KBgf! XCӌbH(u-Z9c-W.6%_6t`ZYxpۙR <޴e÷n^q’f9fP** 1l[?_yyu{^^o/\\GԞ*** 1׼Y^ono7;$**** 1||ͻƛvl8o1ݙ׼;ἼrߐYBC0vNLYZ| yݝ|ԪrBvyN.SV`C;L1İděO9Տ(&Cmqj x' c5tbhœ2BM˓ј9ŐbOO<4 o +Pu]YK&U`vx6yO/yfr>1'4dc9 F(kKe ܿx +,/bU?!Ű>=qdsºZ ZQJHN.] <4 o g1p3xϙ9O;-W.b!aSIW XS Yhgg(ZDArӪ(z̜4#Dz0vK3Tdiy<0'a0'm˓QϜlv39Տb~4_46_bim )fyǜpvE,t!4BSLZbf4aNf\9:xQ(nZr;sB-1;qNc ܴ<5 JPh(K41pr3`N1%sŠ@-pJ`91z6>^wMfy]N0% UsLBT+[z¥B1x4q5\cq |ywh~C ㌌Ca;^~/iy9aN,C3rf \j1͌{1pd bie7-/Gʜ0-YKѮ$جxCeM˷m7Ә>n_^&^bHllK~ T%??_nK~vv]%(tFpJPʕ??_^=qol3ȁUvͻ6-' P$'L G%QCYnwg?_f~rbH1pjcotgnqcf7 eqfvdnoYvorncv7Sgtt\Z,gttZd@L]j7r%T fӪ(Ѫ$LYj7vq%ƕԒb1ϵǥ2LVAr!aJ3v3/>C·op{|-CbkZ1^o#<<2Xj/Bm H1$V@riFnfwPel ^aCi%Rg2]Z U 8ԪivŐXr%_e * ڻgK&ڈffcH ɵ{d .XUk?´HN hw+Cb}5tF UF(tF2U1ӌP.[caiˆ|۟ibarjq^\p{ǥuebHxNJ0,~KBgf! XCӌbH(u-Z9c-W.6%_6t`ZYxpۙR <޴e÷n^q’f9fP** 1l[?_yyu{^^o/\\GԞ*** 1׼Y^ono7;$**** 1||ͻƛvl8o1ݙ׼;ἼrߐYBC0vNLYZ| yݝ|Ȕ e |="84R|f#z-|-zjR2k6r,aLC7N:'<>\6u,krW0k6''఼leCfxzR25â|=&\X Rlz{Ҭ-]p)=ͨd841n4T.#. p 55P5SS2Zk6):,?qj`)E}/bEy,<)tYєKk'X/ˑ5pHl9)QDzV2VÖw7̧= k e8 ڮ2^I%C1SLX#.qU.,I'6bXe=1%1-^/&[\R;oW(YWlj\KQ+b'T)Fk\eXN5,f8AO ƴXױ~džS\6HWIRcȂCO^COLɰ(w;_ذezbXG$!a jh7V+ʥFyi|bȐ~''vrX"1d0VmHzy:OQO(^LX#ۣqG\4C:7+X=neOK c5\!;UP,aL?yzt'Dɧ;8lAO rdzb *%e2rFJ*8 pa5;E򄩼\(wSLX4XJB]j\RJ%kƉ?.;=]_o4%ӱAc瞌i~C+씬VHfC+T|U9 9! s6+Z>T8~\Ic?t_mWğ{/6J%g>uEDaYlW0YWpv).[=(Rۙ+yWɘ QA^uq?U0ű_)y[ sO*w?7DXeU?A3ğ{2}w{mCz-+%ܓ1 [|WR8;K'cw?qCAp';n]YW\ɘ7JӶsğ{2}! s6򀼂1-¹l+%fsO'cw~Qo a6ğ{2}6Jn 瞌i}1-66+i"ܓ1qCiayU?AI˅1-瞌i} ˿AƴJu K'cwߎ7 [ bPT8J:a[a?dLՆBAp aL 톳SҬ+3=Ӿ.ybf]| ܓ1oߎ 㺘{̇ Q^>b^IDn=ӾY 9r.JuUk=Ӿ~CAptCՙBp^`֕f]qk?dL? ~]ѭPY|W@'cw~n(8mq昳*[C|h9/P ,7V09B'cw?M`/ Ug +TJpsOƴPpǑJ`y3ĆC&zܓ1?_m(  =G !B3瞌i,o(-iaz] ğ{2}vPTE^6ğ{2}~C*lE7p%]q͉?dL}Qm(UeWp5ͽdY=ӾPTE^,lE7p%ŇɘՆBQUy尹ğ{2}|C*B︅ͽh =oB{ (r4uma9sOƴv~USRDFLT2.CCP[  !"#$%&'()*+,-./0123456789:;<=o>?@ABCDEFGHIJKLMNOPQRSTUVWXYZחW%wZޘ+==m</? oo+Ӳfn[%hU605>GJz{W2(L~`#İ(G=y%ąNK T2P︅oO5fd t G_kP ԔKk b =1aٸ\=1%-ʑAO^cL/؈X\6X,.wO_ F\b(Gjvn_Vɠd(7!~Sf5oSL|…Z@ DY ]beFXGlm|=bQv DXS^a~+hvnǷU2(CS.uYo.>e82rd8zDYCOL`XwܭV;b@S$a^5VӖ5J_E=e5FL˚ab CL%bC5XbJ82Gqw(k=ļ^6,UlG͞ cZ,#bG6BO^#&x[%i_jW2%EzLhX#CYco uw,5v n٨d852a+lˇ6bl#Oؖ|pW;|W0UXe?t{w_qpG;|W8V)IdžrkBO^7 ݲVS^/&p*)ZcXr<[=Ӿv{F8~a-WrgsOƴル ?~'^O%7y߈?dLÆOJ%ï/J:s7 pF^Cl Ρ- 2ĆØV˫AL1!&Sٌ%ʋơqt)>LAU2_841naLn|"5n111|JOe3*Nl{BLFx =1< Q'cZ,#.Ӊ5{%.Ӊ5 KOl.q`.j)&l˅ױ}S2z ٞ5|}54tSGD'TSnqaJeK"zPU#k*AO ƴwH%bǑJi0'$X6Q_ѝpU.eX =1|JOe3ޡar'dx%Cyi9Xzp*01X~ЬA'd8fOlF. ;<X_ؖO'ЬI{%홌i9%¹ꕪ#-۝JRg:+ƕHx! \ie)AOFćXA &cگ^l#(w;_xk ДKk5/ƴ!&l˅lDqU.,I'6eW2dbńLl.ѰK 0%|| [c=1l'`X0pX^q0}U2% _ eX&7#&k6ruw JRguŵTݐ+{gBQU"ӺpbS%s0rJ z; "X npӋn8+I/Cau|J114Rǚ%a[.f#bU2Бa3 &WbStm/ {c^@sbpXe="+i‡[[{%ï/J*IٞeGD?EI%bBLâ|="&xbBLcوX&>z͔ qX^q:uڣ*Qİ+=ȰeZ&T6J=1~P+,#uSnQ.5_LHA`^oB&re/X…m˧=_LHaLbl5c1/4kk͚GM{;\) 21rǔ XX?`=!-|_b =1M|˜LZɰ|'X?`=%\ض|G,&_?0aYW`)NM{=.l[>!ГX犯5NQ Ju儽}U#q[+9(ڮJ[s.*~:7%ͺr~|U#9[Ugh _?pX ޔ J__^ b 1AO r? K _ OS\L c|#k]*M|#6.bbذP'\X3dFeҸ0La8 |}cگ^l#(GĶ[d5%8#KX\6X,.wOlınUG#6._jL VYܾG1TZ Km qXj5n|"uB;nqer ]%vc\edpq^8,/۸n|"uB;nq[񶇘XbЍW%CdNx- _ WWdفcP8fġqP.5_-. ]ZCO^\b  'EzDM/#S2I~?zd#btU/c Jv'CfЍSdN5z-n+i֕8ηJRur`L?.חW%^/&,2eb F^CO Ïq>hءl4bBZ K{%fs$;2wP.c-z-V)YIL}[UB Q("l 2L1J=14Rǚo a6 r5k艡w7̣<\6J2rF * pz1aᗉ% Ï>GJKlo(k%&>2xXr 0lˇ6"ֺGRO| X5Nqˠ'1,.51i55&>6.GXCȚ&,AO1ļ^6NɀTBO^\bk퓿J8͂AO e%. ҏlĩ)wJ[S\`l#+l$$U7T0`y;;uŭ}S2(IٞɘֵJm!/m̺53lwͱy [JRŠ i̺sw f]aS8T$u5QXek8DFekBItT}B?T7>{%Ӻ%! Ap g* *^/&5=1Bb8Fo r'eb Fv5â|=&. ,5Jcگ^l#Q6ЍSdG. ,584kQ2m\`dV~@YSz*&>-{`{%̺jUҬVWnȬ+q?b QTm;%)(Iٞ 2 (^C'l7QTm;%)(Iٞɬ+3%ͺ2xH>saYW8ˏ"c֝@Π0;aL$|L^r{X(7>@Iz s7V V٢w*I/¡8kuwld%ͺJCDbu!8L^rJRuCDAInל(+I [fqbño^ts':ꆄV}OnqW(iꆄV}Ou1Tn#JRuCVYܾPsչ_P8[ p(z-n+I [fqœjCn19뢛Q%!a,nS0yF7$U7$l{ lP9n(,D:;%s((-WDw*I _i G¹?d[EInHj5{_T6_Д핤ϡ21)&,#Ne%s_l_#;zZIzP &PP앤ꆄV' 8 n|3%?p;%!a,%K0'[ eS2%\b% [& ' V -+I ™iA7N~gf(%sh^65t cZ<XJ!PZIzcL+ *^/&#?w gyYW(rSfȬVXD@7*8sJf>uEf>ycZ^C'l7J114,i')&^L z-|<e2rF%ñndP2dSL zbhʥ5/İqud OS\L C zb0Ţ|=B˖A0Ge85~2a> bbW-ƅa)ֈ5z-Q6}_C;k(nI7~ؿ|{v7^u M}ޜ(Ne7' vd`zCL ߱_ذX׸0,5ayFph a>Qz rd`/ACX&Xq5 ˕f pU.[<C($PE\q bDa~QZ╔$S3% g.`y3z-+INs;n)⚣JR[™ T|U@u1$bq;Kq씤KG;D,("` Jp(8. 2L1 ^T+P>[:sa3U7s m$UG' -,Nɠ$e{M7%4Wm\[ g. 6z-+I|M m/ tivՙ+s;n_HJRg:Vٵ\[X6rtUvJmW+bq;K$_:܉ m/PTE^AYIr"?D)-0/[s%L-B FInAtC) D1- &W\ItwwO\[X JCC[Ad 1-\ UvQ2ѯ/P2(~}yg.l15Jۿ`; &P9%ɉ̺2 Ndq]8S  0Uo a6_$S3% g.;n1#JR1tt_yF?pJҧߨoD[wU,oJi;W>(|V5J;' Cƿbc{ܾWmu7J#~v$;2w&.u1c-L\9r/dycj0D PMIjsKQ2(ٷ+UGooJ:_+uG^P.fɃ3GVQL1t[ ( %}[||uG_ޔuG^P.fɃ3GV`D%Ӻcj0D /ow_:dP2dK aCS.uYMGS`wQa^  ]Neo!85zb0Ţ}U2z75%`L5֋rd#z-rc+{gm;QɠKpJҧߨw;narѭಒ[_z[ ;a;#PÝS(H8;KN`-W>[DE1-z-LAIW\ξ:_Sqlj g.-Ji;_6Ds\w7:V٭$5w(@w%FIQl$;" |!2Cw<\IZk:D? ^w⻒4WUDLo-zv\I*WZ y;n]Iʶ#Q8sߠw⻒Dlw͉Aw%Ӻcj0DqN*/P2(έT(8-*[s7VXY This File AN.NRO 2 SLB This and the following files are all part of NRO, a text formatter descended from ROFF. Unlike other formatters in the library, NRO supports user defined macro-commands. MAN.NRO 1 SLB NRO.C 5 SLB NRO.COM 23 SLB NRO.DOC 16 SLB NRO.H 6 SLB NRO.NRO 11 SLB NROCMD.C 12 SLB NROCOM.C 1 SLB NROMAKE.SUB SLB NROTXT.C 10 SLB SKELETON.NRO SLB DDOCLIB 4 KVL This and the following files comprise DDOCSYS.C 5 KVL a disk 'doctor' program featured in DISKDOC.C 18 KVL Dr. Dobbs Journal (#66, April 1982). DISKDOC.COM 11 KVL DISKDOC.DOC 7 KVL DISKDOC.SYM 4 KVL ANYDISK.C 16 EKR These files are another disk analysis ANYDISK.COM 10 EKR program. This version is descendant from ANYDISK.DOC 8 EKR a program originally written by Richard ANYDISK.OUT 8 EKR Damon. This version is more machine independant and written in a more mainI1m^KGpnmM)i~i ^i j V(@[8wm\nT9JҧraLK\"ØVI2<(T1uG=Q2֝s̅)ެmRmhd{WZ_wdΚ Q{[7E'U>[`aLNlP`o J7B*I6Ji;2(8ѭ yp&JI4Fzn™ Cna6ETUD[-L!(l *6U> Ѧn%i}QqwZmu1c-¹l+$9QP[8DqN(I뎊۟Dr'J 'zgB1(,/iݒ˜(CEo cZ%ApêS3s_ J< =}$ &.m/:ke~<TJ: Iy3U7s m$UG' -,Nɠ$e{M7%4Wm\[ g. 6tainable fashion. .de TH .in 5 .rm 75 .he |$0 ($1)|$2|$0 ($1)| .fo ||-#-|| .in 10 .rm 70 .en .de PP .sp 1 .ti +5 .en .de SH .sp 1 .ti -5 .bo $0 .br .en/* Disk Utility Program for CP/M version 2.x Original May, 1980 by Richard Damon Modified Sept 9, 1981 by Robert Ward Modified July, 1982 by Edward K. Ream Please send all reports of bugs to: Edward K. Ream 1850 Summit Ave. Madison, WI 53705 (608) 231 - 2952 See the file anydisk.doc for documentation. */ #define VERSION "\nJuly 27, 1982\n\n" /* Define the data structures pointed to by the BIOS select disk function. */ /* DPH -- Disk Parameter Header. One for each disk */ struct DPH { /* XLT: address of translation table. */ /* one table for each TYPE of disk */ char *  Y-CATUTLV  8AN NROU|ANYDISK C ~ŒANYDISK COMOANYDISK DOC:WANYDISK OUT? DDOCLIB YmDDOCSYS C v"jDISKDOC C DISKDOC COM'WyDISKDOC DOC~1RDISKDOC SYM.MAN NROmNRO C %NRO COMlNRO DOCz&NRO H &.cNRO NROTSANROCMD C ^BNROCOM C NROMAKE SUBJNROTXT C MU&SKELETONNROV֞ UTILITIES V The files on this disk were submitted by Stephen L. Browning, (SLB), Edward K. Ream (EKR) and Egil Kvalegerg (KVL). Filename KB Author Description ----------------------------------------------------------------- -Catalog d_XLT; /* scratchpad area for BDOS use only */ int d_TEMP1; int d_TEMP2; int d_TEMP3; /* DIRBUF: address of 128-byte directory buffer */ /* all disks use the same buffer */ char * d_DIRBUF; /* DPB: address of DPB. One for each type of drive */ char * d_DPB; /* CSV: address of changed-disk check buffer */ /* one for each drive */ /* size of buffer is DPB -> CSK bytes */ char * d_CSV; /* ALV: address of allocation buffer */ /* one for each drive */ /* size of buffer is (DPB -> DSM / 8) + 1 bytes */ char * d_ALV; }; /* DPB -- Disk Parameter Block One for each TYPE of disk */ struct DPB { /* sector per track */ int d_SPT; /* BSH: block shift factor */ /* BLM = (2 ** BSH) - 1 */ /* BLS: block size. Note size VARIES */ /* BLS = (BLM + 1) * 128 */ char d_BSH; char d_BLM; /* EXM: extent mask */ /* if DSM > = 256 then block numbers take two bytes */ /* Thus, each extent can hold only 8 block numbers */ char d_EXM; ffer [BBUFSIZ]; char buff[80], *bufp, c; char *temp; int mode, nsects, disk, b, i, j; int block, track, sector; /* Sign on. */ printf("Welcome to ddndisk version 3: "); printf(VERSION); /* Initialize */ track = 0; sector = 0; block = 0; mode = PHYS; nsects = 1; /* The default drive is drive A: */ disk = 0; select(disk); for (;;) { bufp = gets(buff); /* The 'X' request must be the only thing on a line. */ if (tolower(*bufp) == 'x' && *(bufp + 1) == '\0') { break; } while (c = *bufp++) switch (toupper(c)) { case 'B': mode = LOG; nsects = SPB; /* Get block number from the user. */ block = getnum(&bufp, 0, BPD-1 ,16); /* Convert block number to track/sector. A loop is used to avoid overflow. */ track = sector = 0; for(b = block; b; b--) { sector += SPB; if (sector >= SPT) { track++; sector -= SPT; } } break; case 'C': /* Fill the buffer with a signed constant. */ temp  /* DSM maximum disk BLOCK number */ /* BLOCKS numbered starting at zero */ /* (DSM + 1) * BLS = # of bytes per drive */ int d_DSM; /* DRM: directory max. directory entries 0 -- DRM */ int d_DRM; /* AL0, AL1: allocation vector for directory */ /* each bit reserves one BLOCK */ char d_AL0; /* high bit = block 0 */ char d_AL1; /* high bit = block 8 */ /* CKS: size of directory check vector (or 0) */ /* fixed media: CKS = 0 */ /* removeable media: CKS = (DRM + 1)/4 */ int d_CKS; /* OFF: track offset. number of skipped tracks */ int d_OFF; }; /* Define BIOS entry points. */ #define SELDSK 9 #define SETTRK 10 #define SETSEC 11 #define SETDMA 12 #define RDSEC 13 #define WTSEC 14 #define SECTRAN 16 /* BE = logical sec # */ /* DE = address of translation table */ /* Set this constant to the number of drives you have. */ #define NDRVS 5 /* Set BBUFSIZ to the size of the largest block that any of your disks use. Set MBUFSIZ to the l= getnum(&bufp, -32765, 32765, 16); for(i = 0; i < nsects * SECSIZE; i++) { buffer[i] = temp[i]; } break; case 'D': /* Select the disk and print disk info. */ disk = getnum(&bufp, 0, NDRVS-1, 10); select(disk); info(); break; case 'E': /* Patch the buffer with a list of chars. */ i = getnum(&bufp, 0, nsects*SECSIZE-1, 16); while(*bufp ==' ') { buffer [i++] = getnum(&bufp,0,255,16); if(i >= nsects*SECSIZE) { break; } } break; case 'F': /* Fill the buffer with an unsigned constant */ i = getnum(&bufp, 0, 255, 16); for(j = 0; j < nsects*SECSIZE; j++) { buffer [j] = i; } break; case 'H': /* Print a help message. */ help(); break; case 'I': /* Enter track/sector mode. */ if (mode != PHYS) { mode = PHYS; nsects = 1; /* Convert block to track/sector. */ track = sector = 0; for (b = block; b; b--) { sector += SPB; if (sector >= SPT) { track++; sector -= SPT; argest number of directory entries that are placed on any of your disks. There is code (in the select routine) which makes sure that these constants are, in fact, large enough. If not, a message is issued and the program aborts, so you shouldn't be able to bomb the program (or your disks). */ #define BBUFSIZ 4096 #define MBUFSIZ 4096 /* Do not change ANY of the following constants. */ #define PHYS 0 #define LOG 1 #define YES 1 #define NO 0 #define SECSIZE 128 #define table TXTABLE /* Define global constants set by the select() routine. */ struct DPH * d_header; /* pointer to DPH */ struct DPB * d_disk; /* pointer to DPB */ int TPD; /* tracks per disk */ int SPT; /* sectors per track */ int BPD; /* blocks per disk */ int SPB; /* sectors per block */ char * TXTABLE; /* pointer to translate table */ int DIRBLKS; /* blocks in the directory */ int DIRSIZE; /* entries in the directory */ int OFFSET; /* offset of first track */ main() { char bu  } } track += OFFSET; } break; case 'M': /* Print the directory and allocation map. */ ptmap(disk, table); break; case 'N': /* Go to next sector or block. */ if (mode == LOG) { block++; sector += SPB; } else { sector++; } if (sector >= SPT) { track++; sector -= SPT; if (track >= TPD) { /* Stop the scan. */ *bufp = '\0'; printf("No next sector.\n"); } } break; case 'P': /* Print the buffer. */ dmpbuff (buffer, nsects, mode, disk, block, track, sector, table); break; case 'R': /* Read a block or sector into the buffer. */ rdbuff (buffer, nsects, mode, disk, block, track, sector, table); break; case 'S': /* Set LOGICAL sector #. Enter track/sector mode. */ if (mode == LOG) { mode = PHYS; track = OFFSET; } nsects = 1; sector = getnum(&bufp, 0, SPT - 1, 10); break; case 'T': if (mode == LOG) { mode = PHYS; sector = 0; } n of range.\n",number); printf("Enter a decimal number "); printf("between %d and %d: ", low, high); } bp = gets(buffer); number = getnum(&bp, low, high, base); } return number; } /* Print a helpful message. */ help() { printf("Commands are...\n\n"); printf("Bn enter block mode and set block n.\n"); printf("Cn fill buffer with short n.\n"); printf("Dn set disk to n and print disk info.\n"); printf("Ea n1 n2 ... edit buffer[a] with n1 n2 ...\n"); printf("Fn fill buffer with unsigned n.\n"); printf("H print this message.\n"); printf("I enter track/sector mode.\n"); printf("M print disk allocation map.\n"); printf("N go to next block or track/sector.\n"); printf("P print buffer.\n"); printf("R read sector or block into buffer.\n"); printf("Sn set current sector to n (first sector is 0).\n"); printf("Tn set current track to n (first track is 0).\n"); printf("W write sector or block from buffer.\n"); printf("X exit program sects = 1; track = getnum(&bufp, 0, TPD - 1, 10); break; case 'W': /* Write the buffer to the disk. */ wrbuff (buffer, nsects, mode, disk, block, track, sector, table); break; case ' ': /* Ignore spaces. */ break; default: /* Unknown request. */ printf("%c ?????\n",c); *bufp = '\0'; break; } /* end switch */ if(kbhit()) getchar(); } } /* Call Bios. Return a word, not just a byte. */ bioshl(function, bc, de) int function, bc, de; { int * p; int q; /* get address of BIOS jump table */ p = 0x0001; q = *p + (3*function - 3); /* go to BIOS */ return call(q,0,0,bc,de); } /* Dump out the buffer in hex and in ascii. */ dmpbuff(pntr, nsects, mode, disk, block, track, sector, table) char *pntr; int nsects, mode, disk, block, track, sector; char *table; { int i,j,lchar; prthdr(mode,nsects,disk,block,track,sector,table); for (i = 0; i < nsects * SECSIZE; i += 16) { if(i % SECSIZE == 0 && mode == LOG) { (must be alone on line).\n"); } /* Print information about the selected disk. */ info() { printf("Disk Parameter Header = %x (hex)\n", d_header); printf("Disk Parameter Block = %x (hex)\n", d_disk); printf("Sector Translate Table = %x (hex)\n", TXTABLE); printf("Track offset: %d\n", OFFSET); printf("Tracks per disk: %d\n", TPD); printf("Blocks per disk: %d, %x (hex)\n", BPD, BPD); printf("Sectors per track: %d\n", SPT); printf("Sectors per block: %d\n", SPB); printf("Chars per block: %d\n", SPB * SECSIZE); printf("Directory blocks: %d\n", DIRBLKS); printf("Directory entries: %d\n", DIRSIZE); printf("\n"); } /* Print the header message of a dump. */ prthdr(mode, nsects, disk, block, track, sector, table) int nsects, mode, disk, block, track, sector; char *table; { printf("\ndisk %c, ", disk + 'A'); if (mode == LOG) { printf("block %d, ", block); } printf("track %d, ", track + (mode == LOG ? OFFSET : 0)); printf("physical sector %d, ", printf("\n\nRecord %d\n", i/SECSIZE); } printf("\n%04x ", i); for (j = 0; j < 16; j++){ if(j%4 == 0) { printf(" "); } if (j%8 == 8) { printf(" "); } printf("%02x", pntr [i+j]); } printf(" "); for (j = 0; j < 16; j++) { lchar = pntr [i+j]; if (lchar < 0x1f || lchar > 0x7d) { printf("."); } else { printf("%c",lchar); } } if (kbhit()) break; } printf("\n"); } /* Get a number from the keyboard. */ getnum(pntr, low, high, base) int low, high, base; char **pntr; { int number; char c, buffer[50], *bp; number = 0; while(**pntr == ' ') (*pntr)++; while((c = toupper(*(*pntr)++))>='0' && c<= '9' || base ==16 && (c-=7) > '9' && c<= ('F'-7)) number = base*number+c-'0'; (*pntr)--; if (number < low || number > high) { if (base == 16) { printf("%x is out of range.\n",number); printf("Enter a hex number between "); printf("%x and %x: ", low, high); } else { printf("%d is out  bioshl(SECTRAN, sector, table)); printf("logical sector %d", sector); printf("\n"); } /* Print the directory and a disk allocation map. */ #define M1COL 3 /* Entries/line: directory */ #define M2COL 16 /* Entries/line: alloc map */ ptmap(disk, table) int disk; char *table; { int count, i, j, k; int track, sector, d, ex; char dir[BBUFSIZ]; /* Current directory bloc. */ int map[MBUFSIZ]; /* The disk allocation map. */ int *intdir, id; intdir = dir; /* Clear the map. */ setmem(&map, 2*MBUFSIZ, 0); printf("The directory is...\n"); track = sector = 0; for (count = i = 0; i < DIRSIZE; i++) { if (i%(4*SPB) == 0) { /* Read the next next block. */ rdbuff (dir, SPB, LOG, disk, 0, track, sector, table); sector += SPB; if (sector >= SPT) { track++; sector -= SPT; } j = 0; } else { j += 32; } /* Skip never allocated entries completely. */ if (dir [j+1] == 0xe5) { continue; } /* Print M1COL  if (d_header == 0) { printf("Select failed!\n"); exit(); } d_disk = d_header -> d_DPB; /* calculate global constants for this drive */ TXTABLE = d_header -> d_XLT; SPB = d_disk -> d_BLM + 1; BPD = d_disk -> d_DSM + 1; SPT = d_disk -> d_SPT; OFFSET = d_disk -> d_OFF; /* Compute number of logical tracks on the disk. For hard disks nsectors can overflow. thus, we must use a for loop instead of: */ /* comment out ----- nsectors = SPB * BPD; ntracks = nsectors / SPT; if (nsectors % SPT != 0) { TPD++; } ----- end comment out */ nsectors = 0; TPD = 1; for (i = 0; i < BPD; i++) { nsectors += SPB; if (nsectors > SPT) { nsectors -= SPT; TPD++; } } /* Add the number of hidden tracks. */ TPD += OFFSET; /* Compute the number of blocks in the directory. */ alloc = ((d_disk -> d_AL0) << 8) | (d_disk -> d_AL1); DIRBLKS = 0; for (i = 0; i < 16; i++) { if ((alloc & 1) != 0) { DIRBLKS++; } alloc = aentries per line. */ if (count%M1COL == 0) { putchar('\n'); } count++; /* Print directory number. */ printf("%3x", i); /* Print '=' for nondeleted extents */ printf("%s", dir[j]==0 ? " = " : " * "); /* Save extent number. */ ex = dir [j + 12]; /* Print the file name and extent. */ dir [j + 12] = 0; printf("%s:%x ", &dir [j+1], ex); /* Skip deleted blocks. */ if (dir [j] == 0xe5) { continue; } /* See whether block # fits in 8 bits. */ if (BPD <= 256){ for(k = 16; k < 32 && dir [j+k]; k++) { d = dir [j + k]; if (d) { map [d] = i; } else { break; } } } else { for(k = 8; k<16 && intdir[j/2 + k]; k++){ id = intdir [j/2 + k]; if (id) { map [id] = i; } else { break; } } } } printf("\n\nThe disk map is...\n\n"); for(i = 0; i < BPD; i++) { if (i%M2COL == 0) { printf("%3x: ", i); } if (map [i]) { printf("%3x ", map [i])lloc >> 1; } /* Compute the number of entries in the directory. There are 4 entries in each 128-byte sector. */ DIRSIZE = DIRBLKS * SPB * 4; /* Make sure the directory buffer is big enough. */ if (SPB * SECSIZE > BBUFSIZ) { printf("Block buffer is too small.\n"); exit(); } /* Make sure the map buffer is big enough. */ if (DIRSIZE > MBUFSIZ) { printf("Map buffer is too small.\n"); exit(); } } /* Write the buffer to the disk. */ wrbuff(pntr, nsects, mode, disk, block, track, sector, table) char *pntr; int nsects, mode, disk, block, track, sector; char *table; { int i; int s; bios (SELDSK, disk); for (i = 0; i < nsects; i++, sector++) { if (sector >= SPT) { sector = 0; track++; } if (track >= TPD) { printf("Write truncated!\n"); return; } bios(SETTRK, track + (mode==LOG ? OFFSET : 0)); s = bioshl(SECTRAN, sector, table); bios(SETSEC, s); bios(SETDMA, pntr + (i * SECSIZE)); /* Force immediate write. *; } else { printf("... "); } if(i%M2COL == M2COL-1) { putchar('\n'); } } putchar('\n'); } #undef M1COL #undef M2COL /* Read a block or sector into the buffer. */ rdbuff(pntr, nsects, mode, disk, block, track, sector, table) char *pntr; int nsects, mode, disk, block, track, sector; char *table; { int i; int s; bios(SELDSK, disk); for (i = 0; i < nsects; i++, sector++){ if (sector >= SPT) { track++; sector = 0; } if (track >= TPD) { printf("Read truncated!\n"); return; } bios(SETTRK, track + (mode==LOG ? OFFSET : 0)); s = bioshl(SECTRAN, sector, table); bios(SETSEC, s); bios(SETDMA, pntr + (i * SECSIZE)); bios(RDSEC); } } /* Select a drive for all future disk operations. drive is 0 for drive A:, 1 for drive B:, etc. */ select (drive) char drive; { int alloc, i, nsectors; printf("select drive = %c\n", drive + 'A'); /* Point at the DPH and DPB. */ d_header = bioshl(SELDSK, drive, 0);  / bios(WTSEC, 1); } } able); bios(SETSEC, s); bios(SETDMA, pntr + (i * SECSIZE)); /* Force immediate write. **K͞+v(v(('+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_ !c ^#Vr+s!e ~#fo\s#r̓c\ ̓P6!s͡(\ ̓e̓c̓a̓Y̓U̓W`iͼ!9(\ ̓e̓c̓a̓Y̓U̓W`iͿ!9(̓U+|Z !U w#w\!c s#r!W 6#6! \+!!P Ͱ!e s#r(̓U+|£ !U w#w!e w#w!W 6#6! \+!!P Ͱ!c s#r(\ ̓e̓c̓a̓Y̓U̓W`i!9((!R n&!̓͡P6(T|6!g9Welcome to ddndisk version 3: July 27, 1982 No next sector. %c ????? ÚÎ!K '!9DM! n&A!͑!! n&! ͔*s#r\|!͑͗\ ~#fo*##s#r\~#fo* s#r\###n&#* s#r\~#fo#*s#r\~#fo*s#r\ ~#fo*s#r! w#w*6#6! w#w͐\! ~#fo\ s#r͐\! ~#fo\s#r*^#Vr+s! ^#Vr+sË*~#fo\s#r\ n&\ nѯg|g}o`is#r*w#w! w#w͐|Ҕ͐|g}o|v*^#Vr+s͐!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-Î!Îi'ü!!GcG% )Ú'ð'!9DM!B͡!b͡!c w#w!e w#w!a w#w!U w#w!W 6#6!Y w#w̓Yͤ! ͧ!P s#r̓Pn&ͪ|T̓P#n}T9!P ^#Vr+sn!R s{+!R n&ͭ>B…>`is#r! ^#Vr+sI\\ ?))*s#r\ ?|!͑͗\|!-͑͗!9select drive = %c Select failed! Block buffer is too small. Map buffer is too small. V!Î!i'G!9DM`iw#w͐;~#fon} ͐;^#Vr+sd͐;^#Vr+sn&J! s!|! n&|͐A|! n&s!|! n&|͐A͐?! nѯg`is#rÁ͐;^#Vr+s͐͐==͐͐?͐A|w͐!M!M͐?͐=!Má͐!!M!6M͐?͐=!NM! P!5 s#r͐A͐?͐=!5 S`is#r͐!79%x is out of range. Enter a hex number between %x and %x: %d is out of range. Enter a decimal number between %d and %d: iÎ!\!f\!=f\ !`f\!f\!f\\!f\!f\ !f\ ?!f\!f\!.f!EfDisk Parameter Header = %x (hex) Disk Parameter Block = %x (hex) Sector Translate Table = %x (hex0 >C‘> >D>X >E©>ʈ >Fµ> >H>n >I>t >M>& >N>9 >P> >R> >S >; >T >ʈ >W! > > - >  !U 6#6\ !W s#r!\+!!P Ͱ!a s#r!e s#r!c s#r̓a![ s#r̓[| !e ~#fo\ s#r̓e\ !c ^#Vr+s!e ~#fo\s#r![ ^#Vr+sÅ (!!!!P Ͱ!S s#r!] w#w̓]̓W?U ̓]`i!S ~#fo̓]ns!] ^#Vr+s (! !!!P Ͱ!Y s#r̓Yͤͳ(!̓W?+!!P Ͱ!] s#r̓Pn}  !] ^#Vr+s`i!!!!P Ͱs̓]̓W?  ñ (!!!!P Ͱ!] s#r!_ w#w̓_̓W?k ̓_`i̓]s!_ ^#Vr+s3 (Ͷ(̓U|# !U w#w!W 6#6!e s#r!c s#r̓a![ s#r̓[| !e ~#fo\ s#r̓e\ !c ^#Vr+s!e ~#fo\s#r![ ^#Vr+sí !c ~#fo\s#r(\ ̓Y͹(̓U+|g !a ^#Vr+s!e ~#fo\ s#rr !e ^#Vr+s̓e\ ) Track offset: %d Tracks per disk: %d Blocks per disk: %d, %x (hex) Sectors per track: %d Sectors per block: %d Chars per block: %d Directory blocks: %d Directory entries: %d MÎ!!J!J! J!(J!PJ!}J!J!J!J!J!J!0J!WJ!J!J!JCommands are... Bn enter block mode and set block n. Cn fill buffer with short n. Dn set disk to n and print disk info. Ea n1 n2 ... edit buffer[a] with n1 n2 ... Fn fill buffer with unsigned n. H print this message. I enter track/sector mode. M print disk allocation map. N go to next block or track/sector. P print buffer. R read sector or block into buffer. Sn set current sector to n (first sector is 0). Tn set current track to n (first track is 0). W write sector or block from buffer. X exit program (must be alone on line). 'Î! (!9DM! !0 s#r!!?! !! s#r! s#r! s#r`is#r͐\͐ ͐ !!͐N â !9ô Î!K !9DM͐A!D!ͮ ͐+| ͐ !O!ͮ ͐ ͐+|͝ \!!!Z!ͮ ͐͐!ͱ !e!ͮ ͐!z!ͮ !!ͮ disk %c, block %d, track %d, physical sector %d, logical sector %d ×!0"ß%!y9DM! `i͑!`i͔!!9!%!9DM! n&Ϳ!|!! n& !! n&&!&!9DM! n&!|#"! n&*"! n&&?"/&&'!!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{ʐ%`in}%z%! ! s#r! 6#6! s! s! s͐n}-"! ^#Vr+s! 4͐n}0"! 4͐n&6"}"! 9""!! s#r! ^#Vr+sn`is{.G#! 9"! s#r! 4! ^#Vr+sn`is`in&<"}Ds#Uʯ#Xʸ#O#C$S8$d%͐~#fo|ү#! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 #! 6#! 6! ~#fo! n&! ^#Vr+s~#fo! 3"ѯgs#rð$! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+sð$! n}K$! 6#6! ^#Vr+s~#fo! s#r͐n}ʰ$͐|ʰ$! ^#V!͐\ ))|̓0͐ ͐!̓0!\ ! !9! ~#fo\ s#r͐ \! ^#Vr+s! ~#fo\s#r! w#w-! ~#fo s#r͐#! n}B͐|Z! `i^#Vr+s͐!͐! n}͝Š!Í!!͐ ! n! s#6͐ ! 6͐͐#! !͐! n}\|x! 6#6͐|u͐͐! n}u͐͐! n! s#6͐ |d͐ )! ͐s#rgu! ^#Vr+s! 6#6͐|!0 ~#fo͐͐)~#fo|!0 ~#fo͐͐)~#fo!0 s#r̓0|̓0)! ͐s#r! ^#Vr+sÁ! ^#Vr+sr!! w#w͐\͐|_͐!͐)! ~#fo|ʏ͐)! ~#fo!×! ͐|³! ! ^#Vr+s1! !09The directory is... %3x = * %s%s:%x The disk map is... %3x: %3x ... 1ë Î!Ú'!9DM͐͐͐͐͐͐ ͐(!9`iw#w͐͐ ?r+s! ^#Vr+sns! ^#Vr+s! ^#Vr+sf$͐6! ! s#r! n}%! ^#Vr+s!|%! ^#Vr+s! n}$!0%! s$͐! ^#Vr+sns{0%! ^#Vr+s%! n}a%! ^#Vr+s!|a%! ^#Vr+s6 :%w%! ^#Vr+s`insÍ%! ^#Vr+s`insn"͐6!9å%(!9DM͐n}%! ^#Vr+sn&͢%í%!9DM! n&|ͯ%! n&|ͩ!9DM! n&|ͯ+&! n&|ͩ5&/&!9DM͐͐ ҃&͐^#Vr+s͐p&͐0x&͐7s!&&͐ ͐͐ ͉͐2&`is͐ ͐͐ )͐2&`in&#&&!9!9DM! n&|ͯ'! n&|ͩ '&!9DM`iw#w͐~#fon& '}Y'͐ ?͐^#Vr+snѯg`is#r'͐`'!9 !j96  #F#xʕ'~#È':w&o !,:woʿ'2w&!o ' . & 7**:Oz(q#'  ( > _ ((7*+++:G_*DM!S(o&7**DM:!t(**͐|±͐+|±͐!+͐!+! w#w͐|9͐|!+͐|!+! ~#fo͐͐n&!+! ^#Vr+s!+! w#w͐|ҷ! ~#fo͐͐n! s#6͐|ڐ͐|ڛ!+é͐!+! ^#Vr+sI.|`i~#fos#rl! +!9 Record %d %04x %02x .%c 4(Î!K !9DM͐! `iw#w͐͐ ͐\h! ^#Vr+s! w#w͐\ڃ!͐͐ +|͝œ\ß!! ͐͐!! s#r͐! ͐͐?! ! `i^#Vr+s! ^#Vr+s5!9Read truncated! 54(Î!K !9DM͐! ,`iw#w͐͐ 0 ͐\ڄ! w#w! ^#Vr+s͐\ڟ!9 /0 ͐͐ +|͝¸\û!! ,͐͐!2! s#r͐! ,͐͐?! ,!!,`i^#Vr+s! ^#Vr+sQ!9Write truncated! Q X(!9DM`i6#6͐~#fo͐?+++! s#r .so roff.mac .rm -5 .cm Documentation for anydisk.c .cm Source: anydisk.doc .he 'ANYDISK''July 27, 1982' .fo ''-#-'' .section The authors .pp The original version of this program was written by Richard Damon. Robert Ward rewrote the program and called it DDNDISK. Edward K. Ream further modified DDNDISK to produce ANYDISK. Please send all reports of bugs to: Edward K. Ream 1850 Summit Ave. Madison, WI 53705 (608) 231 - 2952 .section The commands .pp This program allows the operator to examine and modify a CP/M disk. The commands available are: .in +4 .de point .br .ti -4 .en .point Bn Set current track and sector to point at block n and enter block mode. .point Cn Fill buffer with SIGNED value n. .point Dn Set current disk number to n (0--# of drives-1) and print disk information. .point Ea n n ... n Edit buffer starting from location a. .point Fn Fill buffer with UNSIGNED value n. .point H Print help message. .point I Convd the block. .section The structure of a CP/M 2.x disk .pp Here is a brief description of the CP/M 2.x disk format. Several tracks are typically reserved for the bootstrap and a copy of CCP and BDOS. The number of reserved tracks is determined by BIOS for each type of disk. This number is called the track offset; it is printed by the 'D' command when a disk is selected. .pp Most commands deal with the track offset automatically. The only exception is the 'T' command. When using the 'T' command, you must add the offset yourself. Thus, you can access ANY track with the 'T' command. .pp Tracks following the reserved tracks store data. To speed up disk access, CP/M does not store data in consecutive sectors. The sector translate table converts from logically consecutive sectors to the order that those sectors are actually stored on the disk. (This table is used only on CP/M 2.x versions.) .pp All commands deal with LOGICAL sector numbers. This is whaert block to track and sector and enter sector mode. .point M Print the directory and the disk allocation map. .point N Go to next block or track/sector. .point P Print contents of buffer. .point R Read sector or block into buffer (depending on mode). .point Sn Set current sector to n (0--# of sectors per track-1) and enter sector mode. .point Tn Set current track to n (0--# of tracks per disk-1) and enter sector mode. .point W Write sector or block from buffer (depending on mode). .point X Exit program. .br .in -4 Notes: .list .item Multiple commands may be specified on a line except for the X command which must be the only command on the line. .item Commands may be in upper or lower case letters. .item Spaces are ignored except in the E command where they are used as separaters for the numbers. .endlist Typical commands: d0t0s1rp read in the track 0 sector 1 of disk 0 (drive A) and print it. e1A 4F set buffer location 1A t you almost always want. Whenever a sector is printed, both the logical and physical sector numbers are shown. Thus, if you can find any physical sector if you must. .pp A block is the smallest unit of a disk which can be allocated to a file. The size of a block is a multiple of 128 bytes. The block size is determined by BIOS for each type of disk. The block size is printed by the 'D' command. .pp Several blocks are reserved at the beginning of the disk for the directory. Again, the number of reserved blocks is determined by BIOS for each type of disk. This number is also printed by the 'D' command. .pp The format of each entry of the directory is as follows. Each entry describes one extent of a file. .ne 8 .nf byte 0 : file code : 0 if file exists, 0xe5 if deleted bytes 1- 8 : file name : file name (ascii) bytes 9-11 : file type : file type (ascii) byte 12 : file ext : extent number (binary) bytes 13,14: unused bytes 15 : rec count to 4F and set buffer location 1B to 20. e0a 00w set buffer location 0a to 0 and write buffer. Note no space after last data byte. b0rp print the entire first block. b0irp print the first sector of the first block. .section The disk allocation map .pp The M command prints the directory in two sections. Section 1 is a listing of each directory entry. For instance, entry 15 in the directory would be listed as: 15 = DDNDISK C:0 The equal sign means the entry is valid. A star (*) would be printed instead of the equal sign if the entry were deleted. The number following the colon is the extent number. .pp The second section is a disk allocation map. There is one entry in this map for every block on the disk. If the block is not allocated to any file, the characters "..." appear. Otherwise, a number appears. This number refers to the number of the directory entry which allocated the block. Refer back to section 1 to see which file allocate : count of number of sectors in extent bytes 16-31: map : list of blocks used by this extent .br .fi .pp Please note that byte 15 is NOT a reliable guide to the number of blocks allocated to a file. The way to tell is simply to count the blocks in the map. Block 0 is never allocated to any file and it signals the end of the map. Remember that block numbers take either 1 or 2 bytes depending on whether there are less than 256 blocks or not. .section Differences between DDNDISK and ANYDISK .bulletlist .bullet ANYDISK uses the CP/M 2.x BIOS select disk routine to get the characteristics of the disk dynamically. Thus, different .ul kinds of disks may be used without recompiling the program. .bullet ANYDISK will work even with hard disks. Several arithmetic statements have been converted into loops in order to avoid overflow problems. This also means that a single index variable can NOT be used. Instead, the current block, track and sector numbers a (0--# of drives-1) and print disk information. Ea n n ... n Edit buffer starting from location a. Fn Fill buffer with UNSIGNED value n. H Print help message. I Convert block to track and sector and enter sector mode. M Print the directory and the disk allocation map. N Go to next block or track/sector. P Print contents of buffer. R Read sector or block into buffer (depending on mode). Sn Set current sector to n (0--# of sectors per track-1) and enter sector mode. Tn Set current track to n (0--# of tracks per disk-1) and enter sector mode. W Write sector or block from buffer (depending on mode). X Exit program. Notes: 1. Multiple commands may be specified on a line except for the X command which must be the only command on the line. 2. Commands may be in upper or lower case letters. 3. Spaces are ignored except in the E command where they are used as separaters for the numbers. re maintained separately. .bullet The code that computes the disk map now needs lots less memory. Only one disk block at a time is now loaded into memory. .bullet The disk map now is more readable. The format is useful even for hard disks. Directory entries which have 0xe5 for a file name are completely ignored. .bullet The 'D' command now prints a summary of the characteristics of the selected disk. .bullet The 'H' command is new. It prints a help message. .bullet The 'I' command is now useful for printing parts of a block. For example, to print just the 5'th record of block 20 use: b20i nnnn rp .bullet The 'W' command now tells BIOS that all writes are to the directory. This forces BIOS to do the write at once. .bullet You get a more informative prompt if you type a value which is out of range. .bullet The ptmap routine contains two constants, M1COL and M2COL which control how many entries will be put on each line for the directory  Typical commands: d0t0s1rp read in the track 0 sector 1 of disk 0 (drive A) and print it. e1A 4F set buffer location 1A to 4F and set buffer location 1B to 20. -1- ANYDISK July 27, 1982 e0a 00w Set buffer location 0a to 0 and write buffer. Note no space after last data byte. b0rp print the entire first block. b0irp print the first sector of the first block. The___ disk____ allocation__________ map___ The M command prints the directory in two sections. Section 1 is a listing of each directory entry. For instance, entry 15 in the directory would be listed as: 15 = DDNDISK C:0 The equal sign means the entry is valid. A star (*) would be printed instead of the equal sign if the entry were deleted. The number following the list and the disk allocation map. I use fairly small values because my screen only has 64 columns. Choose the constants you like best. k allocation map. I use fairly small values because my screen only has 64 columns. Choose the constants y ANYDISK July 27, 1982 The___ authors_______ The original version of this program was written by Richard Damon. Robert Ward rewrote the program and called it DDNDISK. Edward K. Ream further modified DDNDISK to produce ANYDISK. Please send all reports of bugs to: Edward K. Ream 1850 Summit Ave. Madison, WI 53705 (608) 231 - 2952 The___ commands________ This program allows the operator to examine and modify a CP/M disk. The commands available are: Bn Set current track and sector to point at block n and enter block mode. Cn Fill buffer with SIGNED value n. Dn Set current disk number to n  colon is the extent number. The second section is a disk allocation map. There is one entry in this map for every block on the disk. If the block is not allocated to any file, the characters "..." appear. Otherwise, a number appears. This number refers to the number of the directory entry which allocated the block. Refer back to section 1 to see which file allocated the block. The___ structure_________ of__ a_ CP__/M_ 2_.x_ disk____ Here is a brief description of the CP/M 2.x disk format. Several tracks are typically reserved for the bootstrap and a copy of CCP and BDOS. The number of reserved tracks is determined by BIOS for each type of disk. This number is called the track offset; it is printed by the 'D' command when a disk is selected. Most commands deal with the track offset automatically. The only exception is the 'T' command. When using the 'T' command, you must add the offset yourself. Ther there are less than 256 blocks or not. Differences___________ between_______ DDNDISK_______ and___ ANYDISK_______ o ANYDISK uses the CP/M 2.x BIOS select disk routine to get the characteristics of the disk dynamically. Thus, different kinds_____ of disks may be used without recompiling the program. o ANYDISK will work even with hard disks. Several arithmetic statements have been converted into loops in order to avoid overflow problems. This also means that a single index variable can NOT be used. Instead, the current block, track and sector numbers are maintained separately. o The code that computes the disk map now needs lots less memory. Only one disk block at a time is now loaded into memory. o The disk map now is more readable. The format is useful even for hard disks. Directory entries which have 0xe5 for a file name are compleus, you can access ANY track with the 'T' command. Tracks following the reserved tracks store data. To speed up disk access, CP/M does not store data in consecutive sectors. The sector translate table converts from logically consecutive sectors to the order that those sectors are actually stored on the disk. (This table is used only on CP/M 2.x versions.) All commands deal with LOGICAL sector numbers. This is what you almost always want. Whenever a sector is printed, both the logical and physical sector numbers are shown. Thus, if you can find any physical sector if you must. -2- ANYDISK July 27, 1982 A block is the smallest unit of a disk which can be allocated to a file. The size of a block is a multiple of 128 bytes. The block size is determined by BIOS for each type of disk. The block size is printed by the 'D' command. tely ignored. -3- ANYDISK July 27, 1982 o The 'D' command now prints a summary of the characteristics of the selected disk. o The 'H' command is new. It prints a help message. o The 'I' command is now useful for printing parts of a block. For example, to print just the 5'th record of block 20 use: b20i nnnn rp o The 'W' command now tells BIOS that all writes are to the directory. This forces BIOS to do the write at once. o You get a more informative prompt if you type a value which is out of range. o The ptmap routine contains two constants, M1COL and M2COL which control how many entries will be put on each line for the directory list and the disk allocation map. I use fairly small values because my screen only has 64 columns. Choose the constants you like  Several blocks are reserved at the beginning of the disk for the directory. Again, the number of reserved blocks is determined by BIOS for each type of disk. This number is also printed by the 'D' command. The format of each entry of the directory is as follows. Each entry describes one extent of a file. byte 0 : file code : 0 if file exists, 0xe5 if deleted bytes 1- 8 : file name : file name (ascii) bytes 9-11 : file type : file type (ascii) byte 12 : file ext : extent number (binary) bytes 13,14: unused bytes 15 : rec count : count of number of sectors in extent bytes 16-31: map : list of blocks used by this extent Please note that byte 15 is NOT a reliable guide to the number of blocks allocated to a file. The way to tell is simply to count the blocks in the map. Block 0 is never allocated to any file and it signals the end of the map. Remember that block numbers take either 1 or 2 bytes depending on wheth best. -4- ts you like #asm ; ; Library specially tailored for Diskdoc ; ; ;Fetch a single byte from the address in HL and ; sign extend into HL CCGCHAR: MOV A,M CCSXT: MOV L,A RLC SBB A MOV H,A RET ;Fetch a full 16-bit integer from the address in HL CCGINT: MOV A,M INX H MOV H,M MOV L,A RET ;Store a single byte from HL at the address in DE CCPCHAR: MOV A,L STAX D RET ;Store a 16-bit integer in HL at the address in DE CCPINT: MOV A,L STAX D INX D MOV A,H STAX D RET ;Inclusive "or" HL and DE into HL CCOR: MOV A,L ORA E MOV L,A MOV A,H ORA D MOV H,A RET ;Exclusive "or" HL and DE into HL CCXOR: MOV A,L XRA E MOV L,A MOV A,H XRA D MOV H,A RET ;"And" HL and DE into HL CCAND: MOV A,L ANA E MOV L,A MOV A,H ANA D MOV H,A RET ;Test if HL = DE and set HL = 1 if true else 0 CCEQ: CALL CCCMP RZ DCX H RET ;Test if DE ~= HL emainder in DE CCDIV: MOV B,H MOV C,L MOV A,D XRA B PUSH PSW MOV A,D ORA A CM CCDENEG MOV A,B ORA A CM CCBCNEG MVI A,16 PUSH PSW XCHG LXI D,0 CCDIV1: DAD H CALL CCRDEL JZ CCDIV2 CALL CCCMPBCDE JM CCDIV2 MOV A,L ORI 1 MOV L,A MOV A,E SUB C MOV E,A MOV A,D SBB B MOV D,A CCDIV2: POP PSW DCR A JZ CCDIV3 PUSH PSW JMP CCDIV1 CCDIV3: POP PSW RP CALL CCDENEG XCHG CALL CCDENEG XCHG RET CCDENEG: MOV A,D CMA MOV D,A MOV A,E CMA MOV E,A INX D RET CCBCNEG: MOV A,B CMA MOV B,A MOV A,C CMA MOV C,A INX B RET CCRDEL: MOV A,E RAL MOV E,A MOV A,D RAL MOV D,A ORA E RET CCCMPBCDE: MOV A,E SUB C MOV A,D SBB B RET ; #endasm /* TAB s5,4 * * system dependant functions for diskdoc * * required are: * botmem,topmem,sysok,conin,conout,const * seldrv,lnext,read,write,rstdrv */ /* * this version is for small C and cp/m 8080 version 2.x. * since bios must  CCNE: CALL CCCMP RNZ DCX H RET ;Test if DE > HL (signed) CCGT: XCHG CALL CCCMP RC DCX H RET ;Test if DE <= HL (signed) CCLE: CALL CCCMP RZ RC DCX H RET ;Test if DE >= HL (signed) CCGE: CALL CCCMP RNC DCX H RET ;Test if DE < HL (signed) CCLT: CALL CCCMP RC DCX H RET ;Common routine to perform a signed compare ; of DE and HL ;This routine performs DE - HL and sets the conditions: ; Carry reflects sign of difference (set means DE < HL) ; Zero/non-zero set according to equality. CCCMP: MOV A,E SUB L MOV E,A MOV A,D SBB H LXI H,1 ;preset true condition JM CCCMP1 ORA E ;"OR" resets carry RET CCCMP1: ORA E STC ;set carry to signal minus RET ; ;Test if DE >= HL (unsigned) CCUGE: CALL CCUCMP RNC DCX H RET ; ;Test if DE < HL (unsigned) CCULT: CALL CCUCMP RC DCX H RET ; ;Test if DE > HL (unsigned) CCUGT: XCHG CALL CCUCMP RC DCX H RET ; ;Test if DE <= HL (unsigned) CCULE: CALL CCUCMP RZ RC DCX H RET ; ;Commonbe used for sector read and write, * character i/o functions use bios directly too. * cp/m "compatible" operating systems will probably * need to have these functions rewritten. */ char *xlt; /* sector xlate table, used by cp/m version */ /* * return pointer to bottom of free memory */ int lastglobal; /* dirty trick, will work in small-c */ botmem() { return &lastglobal; } /* * top of free memory * remember that the stack needs some space too */ topmem() { char *p,topofstack; p=&topofstack; return p-300; } /* * return true if enviroment seems to be ok */ sysok() { char *p; #asm mvi c,12 ;check version number call 5 ani 0f0h cpi 20h ;ver 2.x? jnz nogood mov a,h ora a ;cp/m? jz ok nogood: lxi h,0 ;false if no good pop d ret ok: #endasm p=1; return (*p==3); /* check if xsub or despool is active */ } /* * return conso routine to perform unsigned compare ;carry set if DE < HL ;zero/nonzero set accordingly CCUCMP: MOV A,D CMP H JNZ $+5 MOV A,E CMP L LXI H,1 RET ; ;Shift DE arithmetically right by HL and return in HL CCASR: XCHG MOV A,H RAL MOV A,H RAR MOV H,A MOV A,L RAR MOV L,A DCR E JNZ CCASR+1 RET ;Shift DE arithmetically left by HL and return in HL CCASL: XCHG DAD H DCR E JNZ CCASL+1 RET ;Subtract HL from DE and return in HL CCSUB: MOV A,E SUB L MOV L,A MOV A,D SBB H MOV H,A RET ;Form the two's complement of HL CCNEG: CALL CCCOM INX H RET ;Form the one's complement of HL CCCOM: MOV A,H CMA MOV H,A MOV A,L CMA MOV L,A RET ;Multiply DE by HL and return in HL CCMULT: MOV B,H MOV C,L LXI H,0 CCMULT1: MOV A,C RRC JNC $+4 DAD D XRA A MOV A,B RAR MOV B,A MOV A,C RAR MOV C,A ORA B RZ XRA A MOV A,E RAL MOV E,A MOV A,D RAL MOV D,A ORA E RZ JMP CCMULT1 ;Divide DE by HL and return quotient in HL, r le status, true if ready */ const() { return bios(2,0); } /* * get character from console, no echo */ conin() { return bios(3,0); } /* * put character to console * no character conversion should be performed */ conout(ch) char ch; { bios(4,ch); } /* * select drive, drive name is 'a','b' etc. * set values for track, sector counts and first sector * return true if ok * to find out what this version does, * refer to the cp/m 2.0 alteration guide */ seldrv(drv,pt,ps,pf) char drv; int *pt,*ps,*pf; /* where to put track, sector and firstsector */ { int *dph,*spt,*dsm,*off,halfsecs,trks; char *dpb,*bls; if ((dph=bios(9,drv-'a'))==0) return 0; xlt=dph[0]; /* look at disk parameter header */ dpb=dph[5]; if (xlt) *pf=xlt[0]; else *pf=255&bios(16,0); spt=&dpb[0]; *ps=*spt; /* and at disk parameter block too */ bls=&dpb[2]; dsm=&dpb[5]; off=&dpb[13]; /* this is tricky since /* TAB s5,4 * * diskdoc * a utility for diskette maintainance * * by egil kvaleberg * studpost 111 * n7034 trondheim-nth * norway * * diskdoc is intended for use and distribution * among amateur computer users only. please respect this. * * compile using the Ron Cain small C compiler as distributed * by The Code Works. if you use the version of the compiler shown * in the Dr. Dobbs May 1980 issue, you must ensure that the stack * is properly initialized. if you use another C compiler, you'll * have to revise (parts of) the file ddocsys.c. good luck. */ #define VERSION "ver c - 1 nov 81" #define WHOMADEIT "by egil kvaleberg" /* * constants, change as required */ #define SECLEN 128 /* sector length, 128 or 256 is ok */ #define VOID 229 /* character used when zeroing diskette */ #define DHOME 26 /* default home character */ #define ESC 27 /* lead-in character */ #define CR 13 /* various ascii equates */ #define LF 10 #define unsigned divide isn't supported */ halfsecs=(*dsm+1)<<(*bls-1); trks=((halfsecs/(*spt))*2)+(((halfsecs%(*spt))+(*spt-1))/(*spt)); *pt=trks+*off; return 1; } /* * return next logical track/sector * replace by a call to next() if not required * cp/m version sets sector number according to translate table */ lnext(t,s) int *t,*s; { int l; if (xlt) { l=0; while (xlt[l++]!=*s); if (l>=sectors) { nextt(t); l=0; } *s=xlt[l]; } else next(t,s); } /* * reset the currently selected drive * used prior to any other operation on a drive * no error code is returned */ rstdrv() { bios(8,0); } /* * read sector, false if error */ read(trk,sec,adr) int trk,sec; char *adr; { bios(10,trk); bios(11,sec); bios(12,adr); if (bios(13,1)) return 0; return 1; } /* * write sector, false if error */ write(trk,sec,adr) int trk,sec; char *adr; { bios(10,trk); bios(11,seBS 8 #define QOT 39 /* * globals */ int tracks, /* number of tracks and sectors */ sectors,firstsector; int dfltrk,dflsec; /* default values */ char dfldrv; char secbuf[SECLEN]; /* buffer for patch */ char vfybuf[SECLEN]; /* buffer for write verify */ int home; /* character to move cursor home */ /* * begin */ main() { char cmd; dfldrv='a'; dfltrk=0; dflsec=0; home=DHOME; if (sysok()==0) exit(); nl(); puts("welcome to the world of diskdoc "); nl(); puts(VERSION); nl(); puts(WHOMADEIT); nl(); nl(); puts("kindly enter your request"); cmd=0; while (cmd!='e') { nl(); puts("adapt, backup, compare, exit, patch, scan, test or zero ?"); cmd=getcmd("abcepstz",'e'); if (cmd=='a') adapt(); else if (cmd=='b') backup(); else if (cmd=='c') compare(); else if (cmd=='p') patch(); else if (cmd=='s') scan(); else if (cmd=='t') test(); else if (cmd=='z') zero(); else { nl(); puts("re-insert the system diskette and tyc); bios(12,adr); if (bios(14,1)) return 0; return 1; } /* * bios call * will only work with the original small C * other C compilers will usually have the argument sequence reversed */ bios(fun,arg) int fun,arg; { char *ofs; ofs=(fun-1)*3; #asm pop d ;ofs pop h ;ret pop b ;arg push b push h push d lhld 1 ;get pointer to bios dad d ;add offset lxi d,retn1 push d mov d,b ;arg in de too mov e,c pchl ;go retn1: xchg mov l,a mvi h,0 pop b ;ofs push b mov a,c cpi (9-1)*3 ;select disk function? jz retn2 cpi (16-1)*3 ;sector translate? jnz retn3 retn2: xchg ;value came in hl retn3: #endasm } /* * some small C library functions need redefinition */ #asm ccgo: ret ; qzexit: jmp 0 #endasm  pe "); if (conlower()!=CR) cmd=0; nl(); } } nl(); puts("thanks for having consulted diskdoc"); exit(); } /* * adapt to terminal */ adapt() { nl(); nl(); puts("type character to move cursor home.."); putbyte(home=conin()); if (home==ESC) { puts(".."); putbyte(home=conin()); home=home+128; } nl(); } /* * backup, copy entire diskette */ backup() { int trk,ftrk,ltrk; char sdrive,ddrive; char *adr; if (seltwo(&sdrive,&ddrive, "source diskette in drive (a-h) ?", "destination diskette in drive (a-h) ?")==0) return; if (cont()==0) return; trk=-1; while (nextt(&trk)) { adr=botmem(); ftrk=trk; if (baksel(sdrive,ddrive,"source")==0) return; while (1) { if (readtrk(trk,adr)==0) return; ltrk=trk; adr=adr+(SECLEN*sectors); if ((adr+(SECLEN*sectors))>=topmem()) break; if (nextt(&trk)==0) break; } adr=botmem(); trk=ftrk; if (baksel(ddrive,sdrive,"desti) { secbuf[n]=p[n&31]; ++n; } puts("does diskette already contain test pattern (y-n) ?"); if (getcmd("yn",'n')=='n') { nl(); puts("writing test pattern..."); trk=0; sec=firstsector-1; while (next(&trk,&sec)) { secbuf[0]=trk; secbuf[1]=qskew(sec); if (tstbrk()) return 0; if (write(trk,qskew(sec),secbuf)==0) { nl(); puts("error writing "); putsec(trk,qskew(sec)); nl(); return 0; } } } trk=-1; /* read test */ nl(); puts("reading test pattern..."); while (nextt(&trk)) { if (readtrk(trk,botmem())==0) return; sec=firstsector-1; adr=botmem(); while (nexts(&sec)) { secbuf[0]=trk; secbuf[1]=qskew(sec); if (eqsec(adr,secbuf)==0) { dfltrk=trk; dflsec=qskew(sec); nl(); puts("bad test pattern in "); putsec(dfltrk,dflsec); } adr=adr+SECLEN; } } nl(); puts("test completed"); nl(); } /* * scan: check all sectors for crc errors etc. */ scan() { int trk,sec; nl(); nl(); puts("scannation")==0) return; while (1) { if (writetrk(trk,adr)==0) { puts("backup aborted"); nl(); return; } if (trk>=ltrk) break; nextt(&trk); adr=adr+(SECLEN*sectors); } } nl(); puts("backup finished"); nl(); } /* * compare contents of two diskettes */ compare() { int trk,sec; char drive1,drive2; char *adr1,*adr2; if (seltwo(&drive1,&drive2, "compare diskette in drive (a-h) ?", "to diskette in drive (a-h) ?")==0) return; if (cont()==0) return; trk=-1; while (nextt(&trk)) { adr1=botmem(); adr2=adr1+(SECLEN*sectors); if (baksel(drive1,drive2,"first")==0) return; if (readtrk(trk,adr1)==0) return; if (baksel(drive2,drive1,"second")==0) return; if (readtrk(trk,adr2)==0) return; sec=firstsector-1; while (nexts(&sec)) { if (eqsec(adr1,adr2)==0) { dfltrk=trk; dflsec=qskew(sec); nl(); puts("compare error in "); putsec(dfltrk,dflsec); } adr1=adr1+SECLEN; adr2=adr2+SECLEN;  diskette in drive (a-h) ?"); if (getsel()==0) return; if (cont()) { nl(); trk=0; sec=firstsector-1; while (next(&trk,&sec)) { if (tstbrk()) return; if (sec==firstsector) { puts("track "); putnum(trk); conout(CR); } if (read(trk,qskew(sec),vfybuf)==0) { puts("the dubious quality of "); putsec(trk,qskew(sec)); puts(" has been detected"); nl(); dfltrk=trk; dflsec=qskew(sec); } } puts("scan finished"); nl(); } } /* * patch */ patch() { int pos; nl(); nl(); puts("patch diskette in drive (a-h) ?"); if (getsel()==0) return; if (dflsec=next-byte, =previous-byte, =next-line, , ',"); nl(); puts("next, logical-next, trk-sec, re-read, shift-bit, write or quit ?"); putnls(4); puts(" +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f"); puts(" 0123456789abcdef"); pos=pread();  } } nl(); puts("compare finished"); nl(); } /* * zero diskette contents */ zero() { int trk,trkmax,n,m; char *adr; nl(); nl(); puts("zero diskette in drive (a-h) ?"); if (getsel()==0) return; nl(); puts("zero how many tracks (0-"); putnum(tracks-1); puts(") ?"); trkmax=getnum(tracks-1,0,tracks-1); if (cont()==0) return; n=0; adr=botmem(); m=SECLEN*sectors; while (n=0); putnls(60); } /* * one patch command * return new position, -1 if quit */ patchcmd(pos) int pos; { char cmd,dig; cmd=conlower(); if (cmd=='q') return -1; else if (cmd==' ') pos=(pos+1)%SECLEN; else if (cmd==BS) pos=(pos+SECLEN-1)%SECLEN; else if (cmd==CR) pos=(pos+16)%SECLEN; else if (cmd=='s') pos=pshift(pos); else if (cmd=='n') pos=pnsect(); else if (cmd=='l') pos=plsect(); else if (cmd=='t') pos=psetts(); else if (cmd=='r') pos=pread(); else if (cmd=='w') pos=pwrite(); else if (cmd==QOT) { conout(QOT); cmd=conin(); conout(BS); if (cmd==BS) tbyte(pos); else pos=patchpos(pos,cmd); } else if ((dig=makhex(cmd))>=0) { putdig(dig); while ((cmd=conlower())!=BS) if (makhex(cmd)>=0) break; conout(BS); if (cmd==BS) tbyte(pos); else pos=patchpos(pos,(dig<<4)+makhex(cmd)); } return poscur(pos); } /* * patch one byte, update screen * and return n end of line * 0 if end of page * 1 otherwise */ tbyte(pos) int pos; { putbyte(secbuf[pos++]); /* print byte */ puts(" "); if (pos%16) return 1; puts(" '"); /* print ascii equivalents */ pos=pos-16; while (1) { conout(makep(secbuf[pos++])); if ((pos%16)==0) break; } puts("'"); nl(); if (pos==SECLEN) return 0; putbyte(pos); /* print address too */ puts(" "); return -1; } /* * read one track * assume that drive is already selected */ readtrk(trk,adr) int trk; char *adr; { int sec; char cmd; sec=firstsector; while (1) { if (tstbrk()) return 0; if (read(trk,qskew(sec),adr)==0) { nl(); puts("error reading "); putsec(trk,qskew(sec)); nl(); puts("continue, retry or quit ?"); cmd=getcmd("qcr",'r'); if (cmd=='r') { read(0,firstsector,vfybuf); /* reposition */ continue; } dfltrk=trk; dflsec=qskew(sec); if (cmd=='q') return 0; } ew position */ patchpos(pos,new) int pos,new; { int tpos; secbuf[pos]=new; tpos=pos++; if (pos>=SECLEN) pos=0; while (tbyte(tpos++)>0); return pos; } /* * shift one bit at current position */ pshift(pos) int pos; { int tpos,byte,carry; tpos=pos; carry=0; while (1) { byte=secbuf[tpos]&255; secbuf[tpos]=(byte>>1)|(carry<<7); carry=byte&1; if (tbyte(tpos++)==0) break; } return poscur(pos); } /* * next sector */ pnsect() { next(&dfltrk,&dflsec); return pread(); } /* * next logical sector * useful only in systems with mapping between logical and physical * sector numbers */ plsect() { lnext(&dfltrk,&dflsec); return pread(); } /* * set new track/sector address */ psetts() { gohome(); putnls(2); putsps(38); gohome(); nl(); getsec(&dfltrk,&dflsec); return pread(); } /* * read and display one sector during patch */ pread() { char *p;  adr=adr+SECLEN; if (nexts(&sec)==0) return 1; } } /* * write one track */ writetrk(trk,adr) int trk; char *adr; { int sec; sec=firstsector; while (1) { if (tstbrk()) return 0; if (write(trk,qskew(sec),adr)==0) { nl(); puts("error writing "); putsec(trk,qskew(sec)); nl(); return 0; } adr=adr+SECLEN; if (nexts(&sec)==0) return 1; } } /* * get track and sector numbers */ getsec(t,s) int *t,*s; { nl(); puts("track (0-"); putnum(tracks-1); puts(") ?"); *t=getnum(*t,0,tracks-1); nl(); puts("sector ("); putnum(firstsector); puts("-"); putnum(sectors-1+firstsector); puts(") ?"); *s=getnum(*s,firstsector,sectors-1+firstsector); } /* * get drive name, select and reset * 0 if cannot select */ getsel() { if (seldrv((dfldrv=getdrv(dfldrv)),&tracks,§ors,&firstsector)==0) { nl(); puts("drive not ready"); nl(); return 0; } rstdrv(); return 1; } /* * select two drives  int pos; pos=0; while (pos(sectors-1+firstsector)) { *s=firstsector; return 0; } return 1; } /* * increment track, 0 if no more */ nextt(t) int *t; { if ((++*t)>=tracks) return *t=0; m values */ getnum(dfl,min,max) int dfl,min,max; { int n,digits,newn; char ch; if (dfl>max) dfl=max; n=digits=0; while (1) { if ((ch=conlower())==CR) { if (digits) { if (n>=min) break; } else digits=putnum(n=dfl); } else if (ch==BS) { if (digits) { --digits; n=n/10; unput(); } } else if (((makdec(ch))>=0) & ((newn=n*10+makdec(ch))<=max)) { if ((newn>0)|(digits==0)) { ++digits; n=newn; conout(ch); } } } return n; } /* * make character printing */ makep(ch) char ch; { ch=ch&127; if ((ch>=' ')&(ch<127)) return ch; return ' '; } /* * put track and sector numbers */ putsec(t,s) int t,s; { puts("track "); putnum(t); puts(" sector "); putnum(s); } /* * put decimal number, * return number of digits printed */ putnum(n) int n; { int d; if (n>9) d=putnum(n/10); else d=0; putdig(n%10); return d+1; } /* * put hex byte */ return 1; } /* * return skewed sector number, skew factor is two. * this function is not equivalent to lnext(). * the only purpose of this function is to optimize * scan and backup operations. * hard disks will operate faster without a skew. * hard disk is assumed if there are more than 100 tracks (!). */ qskew(sec) int sec; { if (tracks>100) return sec; sec=sec+sec-firstsector; if (sec>(sectors-1+firstsector)) return sec-sectors+((sectors&1)==0); return sec; } /* * compare two sectors * false if not equal */ eqsec(sec1,sec2) char *sec1,*sec2; { int n; n=0; while (n>4); putdig(n); } /* * put digit */ putdig(d) int d; { if ((d=d&15)>9) conout(d-10+'a'); else conout(d+'0'); } /* * put string */ puts(str) char *str; { while (*str) conout(*str++); } /* * put spaces */ putsps(n) int n; { while (n--) conout(' '); } /* * new line */ nl() { conout(CR); conout(LF); } /* * put newlines */ putnls(n) int n; { while (n--) nl(); } /* * erase previous character */ unput() { conout(BS); conout(' '); conout(BS); } /* * move cursor to home position */ gohome() { if (home>=128) conout(ESC); conout(home & 127); } /* * convert decimal digit, -1 if error */ makdec(ch) char ch; { if ((ch=ch-'0')<0) return -1; if (ch<=9) return ch; return -1; } /* * convert hex digit, -1 if error */ makhex(ch) char ch; { if (ch<'0') return -1; if (ch<='9') return ch-'0'; ifdrv(drv,&dummy,&dummy,&dummy)==0) { nl(); puts(name); puts(" drive is not ready"); nl(); return 0; } return 1; } /* * get drive name, enter with default drive */ getdrv(dfl) char dfl; { return getcmd("abcdefgh",dfl); } /* * ask for continue or quit, true if continue */ cont() { char cmd; nl(); puts("continue or quit ?"); cmd=getcmd("cq",'c'); nl(); return cmd=='c'; } /* * get single character command, * enter with possible commands and default command */ getcmd(cmds,dfl) char *cmds,dfl; { char cmd,ch; while (1) { if ((cmd=conlower())==CR) cmd=dfl; if (member(cmd,cmds)==0) continue; conout(cmd); ch=0; while (ch!=BS) if ((ch=conlower())==CR) return cmd; unput(); } } /* * see if character can be found in a string */ member(ch,str) char ch,*str; { while (*str) if (*str++==ch) return 1; return 0; } /* * get a unsigned decimal number * enter with default, minimun and maximu ((ch=ch-'a'+10)<10) return -1; if (ch<=15) return ch; return -1; } /* * test for break, true if yes */ tstbrk() { if (const()) { nl(); puts("break"); if (cont()==0) return 1; } return 0; } /* * get character, no echo * upper case is converted to lower */ conlower() { char ch; ch=conin(); if ((ch>='A')&(ch<='Z')) ch=ch+'a'-'A'; return ch; } /* * system dependant functions */ #include ddocsys.c /* * the small C runtime library (as shown in the Dr. Dobbs * September 1980 issue and as distributed by The Code * Works) must be named ddoclib and edited * so that it contains the primitive functions only: * ccgchar,ccgint,ccpchar,...,ccmult,ccdiv */ #include ddoclib *% %;!a}2,!",!",!"-A!!H%|:%I!I&I!j&I!{&II!&!9!}!9%!e%-%!9!9ͬ|; !,!! 9%%}!,!!9%%A}͗ | !! 9!9%%!9%%A!,͈$!H%|8 I!K)!9%%!9%%AI!! 9Å !9!Ϳ%-%I!Z)!9|O !9%%!!H%|ʉ ! 9!9*,!͸%-%!9!-%!9|L !,!! 9%%}!,!!9%%A}!9%%!,!H%|3 !9%%",!9%%A",I!r)*,*,!9!9%%!-%é U I!)I! 9II!)i!H%|ʈ |ʂ I!9!-%!9*,!͸%-%!9!9ͬ|w ͗ | !9%%*,H%| !)!9%%&! ͔!!9%%!9%%A!,;$!H%|t !)!9%%!9%%A!)I!9%%",!9%%A",ó !)III!)i!H%|ʦ *,*,h%|ʼ *,",!,!,ͬ!<Z͍!*I!S*!Z!*!*!9-%!9!9%%: -%!b%|0 !<Z;;!9 }!9%!qH%|f !Ϳ%"!9%! H%|ʜ !9!N%|ʊI!&!9!&!e}!9%!aH%|͚Ç!9%!bH%|Ç!9%!cH%|$Ç!9%!pH%|ͅ Ç!9%!sH%|*e Ç!9%!tH%|D́Ç!9%!zH%|^)ÇI!& ! N%|ʄ!9!}ItI!'%3II!;'͆!"-͋*-!H%|!`'͆!"-͋*-!"-I;;!9!9!c'!'͵!9!H%|! 9!H%|5! 9!9!Ϳ%-%!9|!9!-%!9! 9%%-%!9%!9%!'8!H%|ʝ! 9!|>!9%%!9%%!H%|! 9!9! 9%%-%!9!9%%!*,%-%!9%%!*,% !~%|">!9!H%|;>Ý!9!-%!9!9%%-%!9%!9%!'8!H%|ʉ! 9!| !9%%!9%%!H%|!'I! 9!9%%!9%%b%| !9!9!9%%!*,%-%ÉDI!'I! 9;;!9!9!'!'͵!9!H%|[! 9!H%|s! 9!9!Ϳ%9%%!!%-%"!9%!H%| !9!9%%!!͸%!%-%"!9%! H%|!9!9%%!!%-%"!9%!sH%|<!9!9%%ͬ-%"!9%!nH%|_!9v-%"!9%!lH%|ʂ!9͇-%"!9%!tH%|ʥ!9͘-%"!9%!rH%|!9-%"!9%!wH%|!9͋-%"!9%!'H%|^!'͔!!9͆!}!͔!!9%!H%|=!9%%[!9!9%%!9%0-%"!9!9% }!b%|"!9%ͬ!9 }!N%|!9% !b%|ʿË!͔!!9%!H%|!9%%"!9!9%%!9%!ͱ%!9% 0-%!9%%B!,!9%%!9%%}!9!9%%#-%+-%!9%%!b%|ʀ!9!-%!9%%#-%+!T%|ʣÀ!9%%!9! 9%%-%!9!-%!|f!9!,!9%%%!A%-%!,!9%%!9%%!ͣ%!9%%!ͱ%3%}!9!9%%!A%-%!9%%#-%+!H%|cf!9%%B!,!,ͬ-%!9|!9!-%!9!9%%!*,%-%!9%!9%!(8!H%|! 9!9%%!9%%!H%|! 9!9%!9%!!(8!H%|B! 9!9%%!9%%!H%|l! 9!9*,!͸%-%!9|!9%%!9%%!H%|!9%%",!9%%A",I!((*,*,!9!9%%!-%!9!9%%!-%ÀÂI!:(I! 9II!K(i!H%|T! 9I!j(*,!͸%&!(!9*,!͸%!*,!͸%-%!H%|ʺ! 9!9!-%!9!-%!9!*,%-%!9%%!9%%h%| !9%%!9%%#-%+!}!9!-%!9%%!9%%h%|v!9%%!!H%|j! 9!9,I! 9II!(i!H%|ʬ! 9I!(!H%|! 9!9!(-%!9!-%!9%%!h%|8 !,!9%%!9%%!9%%!A%%}!9%%#-%!(!0)!n!nH%|; I!3)!9!-%!9*,!͸!,!,͈#͍!Z!&*͍I!,!,ͬ!9!-%!9%%!h%|!,!9%%#-%+!}͍!Z*,*,!,;$!H%|4!**,*,!*I!*!9!-%B!9%%#-%+|ʀe!B͍!Z!9-%͍!Z!9%%|0*,*,!,͈$!H%|!*0*,*,!,;$!H%|!*0!,!,!H%|0! +!*!B͍!Z!!+!9!9%%!%-%!9%%+-%#|ʌ! ͔!n!9!9%%!%!%-%!9%%!9%%h%|!9%%#-%+ì!9%%!,!9%%#-%+%͋!&+!9%%!%| !!(+!9!9%%!͸%-%!|ʌ!,!9%%#-%+%Ͳ͔!!9%%!%!H%|ʉÌ@!++I!9%%!H%|ʯ!!9%%͋!-+!Ϳ%;!9*,-%!|͗ |!3!9%%!9%%A! 9%%;$!H%|ʿI!0+!9%%!9%%AI!?+!9!Y+!r}!9%!rH%|ʌ!*,!-%!9!9%%-%!9%͔!H!9%%!9!9!9%!A%}!9%! b%!9%!h%A%|!9%! !+!9%%&!+!9%%&!9%%! T%|[!9!9%%! %&-%g!9!-%!9%%! %ͬ!9%%!!9%%!ͣ%ͬ!9%%ͬ!9!9%%!A%-%! T%|!9%%! ͸%!a͔!!9%%!0͔!!9%%%|)!9%%#-%+%͔!!9%%+-%#|H! ͔!*! ͔!! ͔!!9%%+-%#|sIZ!͔!! ͔!!͔!*-!b%|ʥ!͔!*-!A%͔!!9!9%!0͸%}!h%|!Ϳ%!9%! [%|!9%!Ϳ%!9%!0h%| !Ϳ%!9%!9[%|C !9%!0͸%!9!9%!a͸%! }! h%|t !Ϳ%!9%![%|ʐ !9%!Ϳ%x!|ʾ I!,!H%|ʾ !!;!9͆!}!9%!Ab%!9%!Z[%A%|!!9!9%!a!A͸%}!9%3!-;!9!9-%!9%%!,͸%3  S!|X!!!9!-%!9%%%!H%!!,;$!9%%",!9%%A",!9%!qH%|ʿ!3!9!9%%!-%!9!H%|!33!9*,-%!|ʪ͗ |!!9%%!9%%A!9%%͈$!H%|vI!]+!9%%!9%%AI!!9!9%%!-%!9!H%|ʧ!I!l+*,!͸%&!v+!9%%!9%%%%!*,!͸%-%I!z+*,&!+*,!͸%*,&!+!9%%!9%%%%*,*,!͸%*,-%:, %}2,!,!,!,ͦ!!9!H%|ʮI!+I!-$!II! 9%%!9%%:, %}2,}I!9%%! 9%%:, %}!9%%%!,!,!,ͦ!!9-$! 9%%%!9!9!9ͦ!!9-$!9%%*,N%!9%%*,N%3%!9%%*,N%3%|ʥI!+I!!!9%%|!!9%%!9%%%%#-%*,!͸%*,T%| !9%%*,-%!!!9%%%%#-%*,b%|=!9%%!-%!*,!dT%|Y!9%%!9!9%%!9%%*,͸%-%!9$!!$!!9%$!9! !9%!a͸%$-%!H%|!!!9!9%%!)%%"-!9!9%%!)%%-%*-|9"!9%%*-!%-%Z"!9%%!!!$A%-%! 9!9%%!-%!9%%!9%%%%-%!9!9%%!-%! 9!9%%!-%!9!9%%! -%!9! 9%%%%!!9%%%!͸%ͱ%-%!9!9%%!9%%%%%!%! 9%%!9%%%%%!9%%%%!͸%!9%%%%%-%!9%%!9%%! 9%%%%-%!!9*-|$!9!-%*-!9%%#-%+%!9%%%%N%|#Ý#!9%%*,b%|#!9%%!9!-%!9%%*-!9%%%-%+$!9%%!9%%ͬ!!$! !9%%$! !9%%$! !9%%$! !$|ʄ$!!! !9%%$! !9%%$! !9%%$!!$|$!!!9!9%%!͸%!%-%*%PYo&y%-%~og~#fo}}|}o|g}o|g}o|gn%+n%+n%+n%+n%+n%+{_z!{%ɳ7͘%%*,!͸%*,T%|!9%%*,͸%*,!A%!H%!9%%!9!-%!9%%!h%|3!9%%!9%%%!9%%!9%%%N%|#!!9%%#-%!!9%!9%H%|ʅI!+!9%%!+!H%|ʅ!!9%!9!9!9ͦ!!9!H%|I!9%%!+I!!!+!9%;I!+!9!+!c}I!9%!cH%3;;!|!9 }! H%|O!9!9%}!9%!9%%!H%|t !9%͔!!9!}!9%!N%|!9 }! H%|!9%Ët !9%%%|!9%%#-%+%!9%H%|!!;! 9%%! 9%%T%|3! 9! 9%%-%!9!9!-%-%!|ʣ!9 }! H%|ʳ!9%%|ʒ!9%%! 9%%b%|ʏãð!9!9!9%%-%&-%à!9%!H%|!9%%|!9%%+-%!9!9%%! %-%tà!9%Ͷ!b%!9! 9%%! %!9%Ͷ-%! 9%%[%A%|ʠ!9%%!T%!9%%!H%3%|ʠ!9%%#%+͘%+͘%+͘%+zŸ%{!||g}o¤%)²%{ozg%#|/g}/oDM!y%xGyOȯ{_zW%DMzz,&x4&>)<&&D&&}o{_zW=!&&,&,&z/W{/_x/Gy/O{_zW{zwelcome to the world of diskdoc ver c - 1 nov 81by egil kvalebergkindly enter your requestadapt, backup, compare, exit, patch, scan, test or zero ?abcepstzre-insert the system diskette and type thanks for having consulted diskdoctype character to move cursor home....source diskette in drive (a-h) ?destination diskette in drive (a-h) ?sourcedestinationbackup abortedbackup finishedcompare diskette in drive (a-h) ?to diskette in drive (a-h) ?firstsecondcompare error in compare finishedzero diskette in drive (a-h) ?zero how many tracks (0-) ?diskette to test in drive (a-h) ?the test will destroy the contents of the diskette**** diskdoc **** test pattern *does diskette already contain test pattern (y-n) ?ynwriting test pattern...error writing reading test pattern...bad test patte richer dialect of C, you might consider rewriting parts of the program. Except for efficiency, perhaps, there is little reason to take the bother since Small-C is a true subset of C. TALKING TO DISKDOC Diskdoc always tries to give self explanatory prompts. The default value can usually be displayed by typing once. If you should enter an inappropriate character, diskdoc simply refuses to echo it. Entries may be corrected by using the backspace key. A final will, as usual, end the input line. THE COMMAND LEVEL Starting up, diskdoc will enter the command level, requesting a single letter command: a Adapt to terminal type. You will asked to enter the character that will move the cursor home. An escape sequence is acceptable. This is all that is required to adapt diskdoc to virtually any video terminal. It is assumed that the width of the screen is 80 characters. b Backup entire diskette, on a sector-by-sector basirn in test completedscan diskette in drive (a-h) ?track the dubious quality of has been detectedscan finishedpatch diskette in drive (a-h) ?=next-byte, =previous-byte, =next-line, , ',next, logical-next, trk-sec, re-read, shift-bit, write or quit ? +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f 0123456789abcdeferror reading error writingerror reading backerror on read verify00 '' error reading continue, retry or quit ?qcrerror writing track (0-) ?sector (-) ?drive not readydrives are not compatibleinsert diskette drive is not readyabcdefghcontinue or quit ?cqtrack sector breakVER 008 MARG+1,66 Small-C DISKDOC: A REPAIR AND MAINTENANCE UTILITY By Egil Kvaleberg, N-4060 Kleppe, Norway. Appeared in the Dr. Dobb's Journal #66, April 1982. Diskdoc is a utility that, like its name implies, is intended fs. You will be asked to enter the source and destination drive names (a-h). It is crucial to double-check the direction of data flow. The same drive might be assigned as both source and destination, in which case diskdoc will request a diskette change whenever necessary during the copy process. If an error is detected in the source diskette, diskdoc will ask whether the sector read operation should be retried, the error ignored, or the backup aborted. It is recommended to retry a few times before declaring a sector unrecoverable, thereby filtering out intermittently occuring errors. If desired, backup can be aborted by typing any character. c Compare the contents of two diskettes. Every discrepancy will be reported. Abort by typing any character. e Exit. You will be prompted to insert a system diskette before leaving. p Patch. Look at and optionally patch selected sectors. Foor repair and maintainance of diskettes and other random access mass storage media. Tasks accomplished include: i Taking backups (also in a single drive system). ii Verifying data integrity. iii Restoring previously deleted files (by manual patching). iv Repairing faulty sectors. v Debugging disk driver routines and controller hardware. vi Debugging file systems. Diskdoc has been in frequent use for about two years now (including a one year assembly language childhood), and has proved a useful companion when exploring the oh-so-vulnerable world of diskettes. The version listed runs under CP/M, but adapting to other operating systems will probably not be found too difficult a task to accomplish. As explained in the listing, te program is written to be compiled by the Ron Cain Small-C compiler. Small-C is smaller than standard C, and conoisseurs of the C language will find some of the constructions used quite primitive. If you prepare the program for ar patch subcommands, see below. s Scan diskette by reading every sector. The test will quickly locate any sector that doesn't give a proper CRC. The test might be interrupted by typing any character. t Test diskette. A test pattern will be written, and the entire diskette will then be read back and compared. The write operation may be omitted. The command provides useful verification of disk controller hardware and software operation. z Zero diskette. The specified number of tracks will be erased by filling the EBCDIC character 'V' (0E5H). PATCH COMMANDS Move the cursor to the next byte. Move the cursor to the previous byte. Move the cursor down, i.e. 16 bytes forward. To patch, enter the new hex byte directly. After having entered the first digit, a will "undo" it. After having entered the second, the cursor will move to the next byte. ' 09 0210 CC11 1080 CC110 1080 CC111 10A3 CC112 10CB CC113 1166 CC114 1163 CC115 11D0 CC116 1202 CC117 1234 CC118 1265 CC119 0287 CC12 1280 CC120 1330 CC121 12E4 CC122 1330 CC123 130E CC124 1330 CC125 1330 CC126 136E CC127 138C CC128 13AC CC129 022A CC13 13DA CC130 1420 CC131 1440 CC132 148C CC133 1489 CC134 14AF CC135 14D8 CC136 15F4 CC137 14EE CC138 15BF CC139 0287 CC14 158C CC140 15BF CC141 15F1 CC142 1604 CC143 16AA CC144 1619 CC145 1676 CC146 16A7 CC147 17AE CC148 18A5 CC149 0244 CC15 18C1 CC150 190C CC151 193D CC152 1959 CC153 19C3 CC154 19D8 CC155 1A33 CC156 1A23 CC157 1A85 CC158 1A85 CC159 0287 CC16 1AD2 CC160 1B20 CC161 1BC9 CC162 1B4F CC163 1B74 CC164 1B8B CC165 1BC3 CC166 1BC0 CC167 1BCB CC168 1C03 CC169 025E CC17 1C00 CC170 1C33 CC171 1C48 CC172 1DA3 CC173 1CB3 CC174 1C92 CC175 1C8F CC176 1CB0 CC177 1DA0 CC178 1CFE CC179 0287 CC18 1CFB CC180 1DA0 CC181 1DA0 CC182 1DA0 CC183 1DF9 CC184 1E5B CC185 1E67 CC186 1EEE CC187 1F00 CC188 1F01 CC189 0284 CC19 1F29 CC190 1F2A CC191 1F48 CC192  To enter an ascii character, type a single quote followed by the desired character. l Read the logically following sector. This command is useful where a mapping between physical and logical sectors exists, such as in standard CP/M single density diskettes. n Read the next sequential sector. The next track is accessed if the end of the current one is reached. q Quit patch mode. r Re-read. Read the current sector once again. s Shift the rest of the sector one bit-position to the right. This command is useful when attempting to repair sectors where the controller has lost a few bits here and there. t Select a new track and/or sector. w Write back the current sector. Remember to use this command after having made any changes, since no automatic write is performed. REGARDING THE CP/M VERSION The CP/M version, as listed, will adapt to the physical characteris1F5A CC193 1F73 CC194 1FA5 CC195 1FE1 CC196 1FFD CC197 201F CC198 2043 CC199 013A CC2 02E2 CC20 2074 CC200 2090 CC201 20BE CC202 20BE CC203 2113 CC204 21E8 CC205 2239 CC206 225A CC207 2416 CC208 239D CC209 031D CC21 23CB CC210 23F7 CC211 242B CC212 2484 CC213 24D1 CC214 0335 CC22 0344 CC23 050E CC24 039D CC25 039D CC26 043E CC27 03CF CC28 0422 CC29 0174 CC3 043B CC30 0489 CC31 0489 CC32 050B CC33 04C6 CC34 04E1 CC35 055B CC36 0573 CC37 0582 CC38 0713 CC39 028A CC4 05E9 CC40 0613 CC41 0642 CC42 066C CC43 0680 CC44 0710 CC45 06E1 CC46 0754 CC47 07BA CC48 07E6 CC49 01C2 CC5 0820 CC50 082C CC51 0876 CC52 086A CC53 08AC CC54 08CF CC55 08E7 CC56 0938 CC57 0A3B CC58 0985 CC59 0287 CC6 0A3B CC60 09D9 CC61 0A38 CC62 0A55 CC63 0B4F CC64 0A89 CC65 0AA9 CC66 0B4C CC67 0B33 CC68 0B88 CC69 01DC CC7 0C82 CC70 0BB3 CC71 0C77 CC72 0BD2 CC73 0C02 CC74 0C74 CC75 0CA6 CC76 0CBC CC77 0D0B CC78 0D30 CC79 0287 CC8 0D66 CC80 1022 CC81 0D9C CC82 1022 CC83 0DDA CC84 1022 CC85 0E10 CC86 1022 CC87 0E3C CC88 1022 CC89tics of the drive (track and sector counts). This is accomplished by reading the disk parameter block returned by the BIOS drive select call. CP/M version 2.0 or better is required. For drives using sector blocking/deblocking schemes, the sectors that diskdoc works with will not correspond directly to the physical sectors. ADAPTING TO OTHER OPERATING SYSTEMS AND/OR COMPILERS All implementation depandant functions are containded in the file "ddocsys.c". These functions are all very low-level, and thus very non-standard. You will have to write these functions yourself, since no C runtime libraries will support them. If automatic size adaptation and/or logical to physical sector mapping aren't required, the functions seldrv() and lnext(), respectively, can be considerably simplifed. 2649 CC1 0287 CC10 0F5E CC100 0F3D CC101 0F5B CC102 1022 CC103 1022 CC104 0F8B CC105 0FC2 CC106 0FBF CC107 0FED CC108 1022 CC1 01F6 CC9 0E5F CC90 1022 CC91 0E82 CC92 1022 CC93 0EA5 CC94 1022 CC95 0EC8 CC96 1022 CC97 0EEB CC98 1022 CC99 2541 CCAND 25B1 CCASL 25A3 CCASR 2634 CCBCNEG 256E CCCMP 257B CCCMP1 2644 CCCMPBCDE 25C4 CCCOM 262C CCDENEG 25EB CCDIV 2601 CCDIV1 2618 CCDIV2 2621 CCDIV3 2548 CCEQ 251F CCGCHAR 2562 CCGE 2525 CCGINT 251B CCGO 2554 CCGT 255B CCLE 2568 CCLT 25CB CCMULT 25D0 CCMULT1 254E CCNE 25BF CCNEG 2533 CCOR 252A CCPCHAR 252D CCPINT 263C CCRDEL 25B8 CCSUB 2520 CCSXT 2598 CCUCMP 257E CCUGE 258A CCUGT 2591 CCULE 2584 CCULT 253A CCXOR 2153 NOGOOD 2158 OK 029A QZADAPT 02E6 QZBACKUP 1A38 QZBAKSEL 24D5 QZBIOS 211C QZBOTMEM 0524 QZCOMPARE 2186 QZCONIN 20C2 QZCONLOWER 2194 QZCONOUT 2178 QZCONST 1AE9 QZCONT 2C18 QZDFLDRV 2C16 QZDFLSEC 2C14 QZDFLTRK 19CB QZEQSEC 251C QZEXIT 2C12 QZFIRSTSEC 1B1E QZGETCMD 1AD7 QZGETDRV 1C07 QZGETNUM 16AC QZGETSEC 1769 QZGETSEL 1F8D QZGOHOME 2D19 QZHOME 2D1D QZLASTGLOB 2388 QZLNEXT 010D QZMAIN 1FB6 QZMAKDEC 1DB2 QZMAKEP 2004 QZMAKHEX 1BCB QZMEMBER 18CE QZNEXTS 1910 QZNEXTT 18A { printf("nro: cannot create %s\n",argv[i]+1); exit(-1); } else { pout = &oub; } } else { puts("nro: too many output files\n"); exit(-1); } } } for (i=1; ioutfile]\n"); exit(-1); } if (pout != stdout) { putc(CPMEOF,pout); fflush(pout); fclose(pout); } } /* * retrieve one line of input text */ getlin(p,in_buf) char *p; struct _buf *in_buf; { int i; int c; char *q; q = p; for (i=0; i') { if (ofp == 0) { if (!strcmp(argv[i]+1,"$P")) { ofp = 1; co.lpr = TRUE; } else if ((ofp = fcreat(argv[i]+1,&oub)) == ERR)= dc.rmval; pg.eflim[RIGHT] = pg.oflim[RIGHT] = dc.rmval; co.outp = 0; co.outw = 0; co.outwds = 0; co.lpr = FALSE; for (i=0; i= &mac.pbb[0]) { c = *mac.ppb--; } else { c = getc(infp); } return(c); } /* * process input files from command line */ profile() { char ibuf[MAXLINE]; for (dc.flevel=0; dc.flevel>=0; --dc.flevel) { while (getlin(ibuf,&sofile[dc.flevel]) != EOF) { if (ibuf[0] == dc.cmdchr) comand(ibuf); else text(ibuf); } if (dc.flevel > 0) fclose(&sofile[dc.flevel]); } if (pg.lineno > 0) space(HUGE); } /* * process switch values from command line */ pswitch(p,q) char *p; int *q; { int swgood; swgood = TRUE; if (*p == '-') { switch (to':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-è )RXLqMMM)NßoNÞNO!9DM! w#w*6#6! s#r`is#r͡! 6#6! ~#fo! ~#foҊ ! ~#fo! ~#fo)~#fon}-R! ~#fo! ~#fo)~#fon}+†! ! ~#fo! ~#fo)~#foͤ#|ƒ!ͧ| ! ~#fo! ~#fo)~#fon}>| ! ~#fo|l ! ! ~#fo! ~#fo)~#fo#ͪ|! 6#6*6#6i *! ~#fo! ~#fo)~#fo#ͭ! s#rzU ! ~#fo! ~#fo)~#fo#! Ͱ!ͧi **s#r| !& ͳ!ͧ! lower(*++p)) { case 'b': dc.bsflg = TRUE; break; case 'm': if (fopen(++p,&sofile[0]) == ERR) { printf("***nro: unable to open file %s\n",p); exit(-1); } profile(); fclose(&sofile[0]); break; case 'p': set(&pg.offset,ctod(++p),'1',0,0,HUGE); break; case 'v': printf("NRO version 1.0\n"); *q = TRUE; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': pg.lastpg = ctod(p); break; default: swgood = FALSE; break; } } else if (*p == '+') { pg.frstpg = ctod(++p); } else { swgood = FALSE; } if (swgood == FALSE) { printf("nro: illegal switch %s\n",p); return(ERR); } return(OK); } *K͞+[[}'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*^#Vr+s! 6#6! ~#fo! ~#fo҄ ! ~#fo! ~#fo)~#fon}-v ! ~#fo! ~#fo)~#fon}+v ! ~#fo! ~#fo)~#fon}>v *r! ~#fo! ~#fo)~#foͶ`is#rzg ! ~#fo! ~#fo)~#fo!B Ͱ!ͧv ͹*rͼ! ^#Vr+sÓ `i~#fo|œ ! ~#fo|ʭ ! ~#fo|ҽ !_ ͳ!ͧ*~#fo+| *~#fo!Ϳ*~#fo*~#foͼ!9$Pnro: cannot create %s nro: too many output files nro: unable to open file %s Usage: nro [-n] [+n] [-pxx] [-v] [-b] [-mmacfile] infile ... [>outfile] !9DM*6#6*##6#6*w#w*6O#6*w#w* w#w* w#w*w#w*6#6*w#w*w#w*6#*6.*6#6*w#w`iw#w`i~#fo|҆ `i~#fo)*w#w`i^#Vr+sV *Rw#w*T6#6*Vw#w*X6B#6*Z6#6*\6#6*^6#6*`6#6*X~#fo*`~#fo*^~#fo*bs#r*dw#w*fw#w*h60#6u*B s*zs* s* s`i6#6`i~#fo8| `i~n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y#fo*z`i~#fo*Bss`i~#fo* `i~#fo*ss`i^#Vr+sn *~#fo*ns#r*js#r*~#fo*vs#r*rs#r*~#fo*ps#r*ls#r*~#fo*xs#r*ts#r*w#w*w#w*w#w*w#w`iw#w`i~#fo8|`i~#fo*6`i^#Vr+sÓ`iw#w`i~#fo|`i~#fo)*w#w`i^#Vr+s*Rw#w*V*Ts#r*&!w#w!9DQ)NMRXßoN!9DM`i6#6! ~#fon}-! ^#Vr+sn&,>b‚>!>mŽ>0>pš>{>v¦>ʰ>0²>>1¾>>2>>3>>4>>5>>6>>7>>8>>9>*6#6*r! ^#Vr+s/#|i! ~#fo!V2!58*r;!!!!1! ^#Vr+sA*d>!v2! ~#fo6#6! ~#foA*hs#r`iw#w$! ~#fon}+! ^#Vr+sA*fs#r$`iw#w`i~#fo|G! ~#fo!2!M!M!9***nro: unable to open file %s NRO versio~#fok*r!k ~#fo͒Ù *r* !k ~#fo͕Ù *j*z!k ~#fo͕Ù ! ͘Ù ͏*6#6Ù *r* !k ~#fo͕*v*!k ~#fo͕Ù *j*z!k ~#fo͕*n*B!k ~#fo͕Ù *~#fo+!!! n&! ~#fo*͉*~#fo*s#rÙ *6#6Ù !!!! n&! ~#fo*##͉Ù !!!! n&! ~#fo*Z͉Ù !!!! n&! ~#fo*\͉Ù !!!! n&! ~#fo*^͉*X~#fo*`~#fo*^~#fo*bs#rÙ !!!! n&! ~#fo*`͉*X~#fo*`~#fo*^~#fo*bs#rÙ ! !k ~#fo͛Ù ͏*b~#fo*V~#fo#! ~#fo*##~#fo?ҩ!͌Ù ͏*w#wÙ *w#wÙ !k ~#fo͞!k s#r!k ~#fo͡!k s#r!k ~#fon&ͤ|! ͘×!k ~#fon&ͧ! s#r!k ~#fo͞!k s#r! !k ~#fo͆! s#r!!!! n&! ~#fo! ~#n 1.0 nro: illegal switch %s ñÎze2oNU!!89DM*w#w*~#fo|i*~#fok*r`i͢#|$`in*n}`iͥ!`iͨ*~#fo|X*~#fok*rͫ*^#Vr+s*V~#fo|څ!ͮ!9×ÓWQ!9DM! ~#fo! s#r`iw#w`i~#fo9|p! ~#fo͑! s#r! ~#fo|! ~#fo#|8! ~#fo6! ~#fo͔! s#r! ~#fo|͝-!5! ~#foÊ! ^#Vr+s! ~#fos! ~#fo|dp`i^#Vr+sõ! ~#fo6! ~#fo͔Ê!9ÙÔQ!9DM*&!~#fo*(!*&!^#Vr+sn`is#6! ~#fo͖`is#r`i~#fo!9Z4Ñ4!9DM! n} ) )+B-bÅ! ~#fo! ~#fos#rÞ! ~#fo~#fo! ~#fos#rÞ! ~#fo~#fo! ~#fos#rÞ! ~#fo! ~#fos#rÞ! ~#fo! ~#fo! ~#fo~#fos#r! ~#fo! ~#fo! ~#fo~#fos#r"!9DM`iw#w! ~#fon}h! ^#Vr+sn&! s#r! ~#fo#|H`i~#foq`i~#fo ?! ~#fo`is#r`i~#foq!9óR"fo)*͉Ù *v*!k ~#fo͕Ù *n*B!k ~#fo͕Ù ! n} ! n} *6! n*sÙ !*Z~#fo*\~#fo*^~#fo*`~#fo#!B! n&! ~#fo*X͉*X~#fo*^~#fo*`~#fo*bs#rÙ !!!! n&! ~#fo*d͉Ù !*~#fo#!P! n&! ~#fo*͉Ù !k ~#fo͞!k s#r!k ~#fo͡!k s#r! !k ~#foͪ|_Ù *~#fo#|ڄ!!͘!ͭ*~#fo#k*r! Ͱ#|! !:!̀!ͭ*^#Vr+sÙ !!!! n&! ~#fo! ͉! ~#fo͌Ù ͏*~#fo!!! n&! ~#fo*͉Ù !!!! n&! ~#fo* ͉*s#r*s#rÙ !g9*** nro: unrecognized command %s ***nro: missing .de command ***nro: invalid or missing number register name ***nro: .so commands nested too deeply ***nro: unable to open %s g!Ó(k6ü7Z4G8!9DMX!*V~#fo*MÌ&(U!Ó(%)+Mç+h..lRQ4RX)N!9DM! !k ~#fo}`is#r`i~#fo#|!k ~#fo! ̀Ù ! !k ~#fo̓! !k ~#fo͆! s#r`i~#fo>5>>A>&>M>ʓ>Y>ʙ>e>>q>> }>2>!‰>|>•>ʩ>¡>>"­>>¹>>>>>G>>ʈ>>>>>>> >H>>y>%>>1>M>=>c> I>ʬ>U>ʹ>#a>>m>ʚ>y>ʼ>…>> ‘>>>ʯ> ©>>µ>> >> > >>O Ù !!!! n&! ~#fo*͉* s#r*s#rÙ *V~#fo|B!͌!!*R~#fo#! n&! ~#fo*R͉*R~#fo*Ts#rÙ ͏Ù !!!! n&! ~#fo*͉Ù ! n} ! n} *6.! n*sÙ ͏!!!! n&! ~#fo* ͉Ù !!!! n&! ~#fo*͉*s#r* s#rÙ *b~#foҒ!*V~#fo|¥![!*b~#fo#*V~#fo! ~#foa!^!*V~#fo! ~#fos#r*V~#fo*b~#fo"d!!9DM! n&|="! n&|C"!N"! n&a"4/æRQ!9DM! ^#Vr+s! ! ~#foU"! 6! X"! s#rz"! ~#fo! ~#fo["!Ã&! ^#Vr+sn&^"`is! ~#fon&^"! s`in}b #! n}o #!Ã&`in}b##! n}p##!Ã&`in}b=#! n}r=#!Ã&`in}bW#! n}sW#!Ã&`in}cq#! n}cq#!Ã&`in}c‹#! n}e‹#!Ã&`in}c¥#! n}u¥#! Ã&`in}d¿#! n}e¿#!!Ã&`in}e#! n}f#!Ã&`in}e#! n}h#!Ã&`in}e $! n}n $!"Ã&`in}f'$! n}i'$!Ã&`in}fA$! n}oA$!Ã&`in}h[$! n}e[$!Ã&`in}iu$! n}nu$!Ã&`in}j$! n}u$!Ã&`in}l©$! n}s©$!Ã&`in}m$! n}1$!Ã&`in}m$! n}2$!Ã&`in}m$! n}3$!Ã&`in}m%! n}4%!Ã&`in}n+%! n}e+%!Ã&`in}nE%! n}fE%! Ã&`in}n_%! n}j_%!Ã&`in}ny%! n}ry%!#Ã&`in}o+s9,! ~#foͰ++`is#r`i~#fo|_.`i~#fo|:.! ~#fo`i~#fo+n}$:.! ~#fo`i~#fon&ͳ+|.! ~#fo`i~#fon&Ͷ+7.! ~#fo`i~#fon&)! ~#fo͹+`i^#Vr+sS.! ~#fo`i~#fon&Ͷ+`i^#Vr+sÙ-!9!9DM! ~#fon} .! ~#fon} .! ~#fon} .! ~#fon} .! ~#fon}.! ^#Vr+sp.! ~#fo!9DM! ~#fon} .! ~#fon} /! ^#Vr+s.! ~#fo/L!9DM*R~#fo`is#r`i~#fo|ڎ/`i~#fo)*~#fo! ~#fo/|‚/`i~#fo)*~#fo###Ô/`i^#Vr+s3/!Ô/!9!9DM! ~#fon} 0! ~#fok|/! ~#fo! ~#fo+6!! ~#fo! ^#Vr+s! ^#Vr+snså/! ~#fo! ~#fo6! ~#fo60WQæR!9DM*R~#fo|W0!*T~#fo! ~#fo00! ~#fo00#*&!җ0!*R^#Vr+s*R~#fo)**T~#fos#r! ~#fo*T~#fo30! ~#fo*T~#fo! ~#fo00#30*T~#fo! ~#fo00! ~#fo00##s#r!T1MRX!9DM*&!~#fo*(!ҡ1*(!*%! n}f“%!Ã&`in}o­%! n}h­%!Ã&`in}p%! n}c%!Ã&`in}p%! n}l%! Ã&`in}p%! n}o%!Ã&`in}r&! n}m&! Ã&`in}s/&! n}o/&!Ã&`in}sI&! n}pI&! Ã&`in}tc&! n}ic&! Ã&`in}u}&! n}l}&!Ã&!Ã&!9Û&QlR8æR!9DM! ~#fo`is#r! ~#fo! s#r`i~#fon}'`i~#fon}@&! ^#Vr+s`i^#Vr+sns'`i~#fo#n}@/'! ^#Vr+s`i^#Vr+sns`i^#Vr+s'`i~#fo#n&͏&|½'`i~#fo##n&͒&|ʽ'`i~#fo##s#r! ~#fo!! ~#fo`i~#fon&͏&)*~#fo͕&+s#r`i^#Vr+s'! ^#Vr+s`i^#Vr+sns&! ~#fo6! ~#fo! ~#fo͘&!9(h..!9DM! ~#fo (! s#r! ~#fo (! s#r! ~#fo! ~#fons! ~#fon}+w(! ~#fon}-‚(! ^#Vr+s! ~#fo(Ù(3:*~#fo|)*~#fo*6 *~#fo#*6 *~#fo##*6*͖(*w#w*w#w*w#wF)h..4lRMRXÎQÝ/-0!\9DM! ~#fo()! s#r! ~#fo+)! s#r! !&!s#r*&!~#fo! ns1*&!~#fo*!1!1N1!Q1*&!^#Vr+s! ns***nro: push back buffer overflow 2WQK1!9DM! ~#fo 2+`is#r`i~#fo|\2! ~#fo`i~#fon& 2`i^#Vr+s,2!9À2Ø<Ì&Î=G?@3:4!A!69DM! ~#fon} ʵ2! ~#fon} ʵ2! ~#fon} 2! ~#foh2! ! ~#fok2* ~#fo|3!! ! ~#fon2* ^#Vr+s*~#fo|I3!! ! ~#fon2*^#Vr+s*~#fo|ڃ3!! ! ~#foq2*^#Vr+s* ~#fo|3! ~#fot2! ~#fow2* ^#Vr+sQ4! ~#fon} 3! ~#fon} 3! ~#fow2Q4*~#fo| 4! ~#fow2Q4! ! ~#foz2`is#r!|Q4! }2! ~#fo`i~#fos#r 4!9!9DM! ~#fo! ~#fo҅4! ~#foÍ4! ~#fo!9DM! ~#fo! ~#foҼ4! ~#fo4! ~#fo4S!9DM`iw#w! ~#fon} 4! ~#fon} 5`i^#Vr+s! ^#Vr+s4! ~#fo! s#r! ~#fon} ʟ5! ~#fon}ʟ5! ~#fon} ʟ5! ~#fon} k5! ~#fon} n5ß5! ~#fo! ^#Vr ~#fo.)`is#r! n&1)|²)!*4)!7)`i~#fo|)! 6`iw#w! ~#fo! ~#fo:)#|t*! ~#fon*n}:*! ~#fo#n&=)|:*! ~#fo##n&=)|:*t*`i~#fo! ! ~#fo@)`is#rzq*!*4)!7))! ! C)#|™*!*4)!7)!9***nro: missing or illegal macro definition name ***nro: macro definition too long ***nro: macro definition table full (+h..æR!9DM! ~#fo+! s#r! ~#fo"+! s#r! ~#fo! ~#fo%+! ~#fo*~#fos#r! ~#fo##*~#fos#rü+h..WQRK12!9DM! ^#Vr+s6`iw#w`i~#fo|,`i~#fo)! ! ~#fos#r`i^#Vr+s+! ~#foͪ+! s#r! ^#Vr+s6`iw#w`i~#fo|҅-! ~#foͭ+! s#r! ~#fon} ʉ,! ~#fon} ʉ,! ~#fon}Œ,Å-! ~#fon}'ʪ,! ~#fon}":-! ^#Vr+sn! s`i~#fo)! ! ~#fos#r! ~#fon! n}(-! ~#fon} (-! ~#fon} (-! ~#fon}(-! ^#Vr+s,! ^#Vr+s6y-`i~#fo)! ! ~#fos#r! ~#foͪ+! s#r! ^#Vr+s6`i^#Vr+sns! ^#Vr+s`i^#Vr+s!5! ~#fo+n! s! n}"5! ~#fo++n! s! n}?5! n}!5! ^#Vr+s6 `i^#Vr+s! n}.O6! ~#fon} 76! ~#fon} 76! ~#fon&4|O6! ^#Vr+s6 `i^#Vr+s! ~#fo6`i~#fob6!9t6ü7ØC*T~#fo*Rs#r*R~#fo*f~#fo6*R~#fo*h~#fo6*6#66*w#w*T^#Vr+s*~#fo+|”7*Z~#fo|ڄ7*Z~#fo+n6*R~#fo|b7*R~#fo*j*zq6Ä7*R~#fo*n*Bq6*\~#fon6*Z~#fo*\~#fo#*Vs#r7F!9DM*~#fo+|>8! ~#fo|>8`iw#w`i~#fo! ~#fo)8*~#fo! Ϳ7`i^#Vr+s7*~#fo! Ϳ7!9P8ü7ØC*~#fo+|8*^~#foJ8*`~#fo|8*R~#fo|8*R~#fo*r* M88*R~#fo*v*M8*`~#fo+J88LS!9DM! ~#fo8! s#r`i6! 6#6! ^#Vr+s`i! ~#fo 0s! ~#fo s#r! ~#fo|ڍ9! ~#fo!~#fo! s#r*~#fo|A*~#fo`i~#fo! ~#foA! ~#fo7|B! ~#fo*~#fos#r*~#fo+|B! ~#fo*~#fo#! s#r*~#fo++*n} dB*^#Vr+s! ^#Vr+s*~#fo! ~#fo*~#fo+**A! ~#fo|B*~#fo|B*~#fo! ~#fo+s#r-A! ~#fo! s#r*~#fo*! s#r! ~#fon}6C! ^#Vr+s! ^#Vr+snsC! ~#fo*s#r*^#Vr+s*6 *~#fo`i~#fo#s#r*^#Vr+s! 9öC8IÛJsKKbLWQFnG!e9DM!! ! ~#fo͛C`iw#w`i~#fo8|D`i~#fo! 6 `i^#Vr+sC! ^#Vr+sn! s! n&! ! ~#fo͞C! s#r! *n&! ͡C! ~#fo~#fo! ! ͤC! n&! ! ~#fo͞C! s#r! *n&! ͡C! ~#fo! ! ͧC! n&! ! ~#fo͞C! s#r! *n&! ͡C! ~#fo##~#fo! ! ͪC`i6#6`i~#fo! n} _E`i~#fo! 6`i^#Vr+s2E`i^#Vr+s! 6 `i^#Vr+s!  ~#fo'9! ~#fo|9! ~#fo! ~#fo9! ^#Vr+s`i6-! w#w! ~#fo! ~#fo:! ^#Vr+s! ~#fo! ~#fo+`ins! ^#Vr+s9! ~#fo*:!9K:k6TFFnGü7Z4G8!69DM*V~#fo|ʁ:*V~#fo*b~#fo҄:6:*~#fo+|<*~#fo|\;`i! ~#fo9:+|\;! w#w! ~#fo*d~#fo;*~#fo! <:! ^#Vr+s:! w#w! ~#fo*~#foH;*~#fo! <:! ^#Vr+s ;*~#fo`i?:! w#w! ~#fo*d~#foҢ;*~#fo! <:! ^#Vr+sd;! w#w! ~#fo*~#fo;*~#fo! <:! ^#Vr+sê;*~#fo! ~#fo?:*~#fo*s#r*b~#fo*V~#fo*##~#fo+E:B:*V~#fo*##~#fo*Vs#r*V~#fo*b~#foҏ! ~#fo! ~#fo+>! ~#fo`i~#fon&|ڜ>! ~#fo`i~#fon&|Ҝ>! ~#fo`i~#fon&͑=|h>! ~#fo`i~#fon&͔=|h>*~#fo|ڜ>! ~#fo! ^#Vr+s6_! ~#fo! ^#Vr+s6! ~#fo! ^#Vr+s! ~#fo`i~#fons`i^#Vr+sí=! ~#fo! ^#Vr+s6 ! ~#fo! ~#fo6! ~#fon}4?! ^#Vr+s! ^#Vr+sns?! ~#fo6!9P?lRR!9DM! w#w`iw#w! ~#fo`i~#fon} U@! ~#fo! ~#fo+U@! ~#fo`i~#fon&J?|?! ~#fo`i~#fon&M?|@! ~#fo! ^#Vr+s! ~#fo`i~#fons! ~#fo! ^#Vr+s6! ~#fo! ^#Vr+s! ~#fo`i~#fons`i^#Vr+sf?! ~#fo! ^#Vr+s6 ! ~#fo! ~#fo6! ~#fon}ʳ@! ^#Vr+s! ^#Vr+snsÄ@! ~#fo6!9@Ñ4îG!9DM!*~#fo*~#fo! ~#fo@@*s#r0AîGWQ,HÓ(!9DM! ~#fo$A`is#r! ~#fo'A*~#fo! s#r*~#fo* ~#fos#r! ^#Vr+s! ~#fo|I! ^#Vr+s! ~#fo! ~#fo6 ! ^#Vr+sÜI`i^#Vr+s! ^#Vr+sH! 9!9DM! ~#fon! n}eJ! ~#fon} eJ! ~#fon} eJ! ~#fon}eJ! ^#Vr+s! ^#Vr+snsJ! ~#fo6! ~#fon! n}J! ^#Vr+s! ~#foáJæR!29DM! ~#fo! s#r`i! s#r! ~#fon}OK! ~#fon! n}(K! ~#fo! s#r! ~#fon}%K! ^#Vr+s! ^#Vr+snsJAK! ^#Vr+s! ~#fons! ^#Vr+sJ! ~#fo6`i! ~#fo͞J!9!9DM! ~#fo! ~#fo! s#r! ~#fon}K! ^#Vr+s! ^#Vr+snsÖKKîG!9DM! ~#foK`is#r! ~#fo! ~#fo##~#fo! ~#fo~#fo`i~#fo! s#r! ~#fon}YL! ^#Vr+s! ^#Vr+sns*L!9hLîG!9DM! ~#foeL`is#r! ~#fo! ~#fo`i~#fo! s#r! ~#fon}L! ^#Vr+s! ^#Vr+snsêL!9!9DM`iw#w! ~#fo͐n! ~#fo͐n} _ ºX7,2q*&:q):Y=Y=r:qo&#7:)~:,"s!"u*|*usY*~#JY"*s*usY#"u*+"7Y7*|D͐tMs#rzҜM!͐͐s#r͐##6#6͐~#foMoSM!y9DM! `iM`iM!9M×X!9DM͐n}'N! ^#Vr+sn&MN/NX!9DM͐!͐,Ns#rzYN!͐##w#w͐~#fouN Y!9DM͐ڍN!͐~#forNêN×XUX Y!9DM͐SO͐>N>N>N>O>N>O>N>(OSO! n&͡N! n&!ͤN! n&!ͤN! n} @O! !ͤN! n&!ͤN͐##^#Vr+s|²O!͐͐~#foͧN|ʑO!͐##6#6͐͐s#r͐^#Vr+s! ns&O YuYY!9DM͐O!Q͐##~#fo|P!Q͐##~#fo`is#r͐͐͐~#foO͐]P!Q͐+?`is#r͐##~#fo|P!͐͐͐O͐##~#fo͐s#r͐~#fo͐s#r!!͐~#foOQ͐##6#6͐͐s#r!Q!9#QV!9DM! n& Q|JQ! n& QQ! n&&!9DM`iw#w! ^#Vr+sn}ʄQ`i^#Vr+M**ڤY>Goy[$F NRO (1) CP/M Version 2.2 NRO (1) NAME NAME nro - text processor SYNOPSIS SYNOPSIS nro n n pxx v b mmfile ifile ofile nro [-n] [+n] [-pxx] [-v] [-b] [-mmfile] ifile ... [>ofile] DESCRIPTION DESCRIPTION ___ NRO is a text processor and formatter based on the design seQ͐ËQ!9àQ1ZUXfZ!9DM͐|·Q͗QcR͐+++|Q!͚QcR͐##^#Vr+s|LR!͐͐~#fo͝Q`is#r!|R͐##^#Vr+scR͐##͐?+s#r͐͐s#r͐^#Vr+sn&cR!9uRVS!9DM! n&oR|ͣ¢R! n&rR|ͣ!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{RøR͐R!9!9DM! n&|ͯS! n&|ͩ!9DM! n&|ͯHS! n&|ͩ!9DM͐|gS͐kS͐~S WRõWX!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{V`in}%¹V! ! s#r! 6#6! s! s! s͐n}-T! ^#Vr+s! 4͐n}0T! 4͐n&uS};T! xS>T!! s#r! ^#Vr+sn`is{.†T! xS! s#r! 4! ^#Vr+sn`is`in&{S}DʲTUTXTOUCFUSwUãV͐~#fo|T! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 U! 6U! 6! ~#fo! n&! ^#Vr+s~#fo! rSѯgs#rU! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+sU! n}Š Software Tools provided in "Software Tools" by Kernighan and Plauger. The ________ text and commands found in the ifile(s) are processed to generate formatted text. The output may be directed into a _____ file or to the printer if ofile is present in the command line; otherwise, the output will appear at the user P console. Directing the output to the special filename, $P, will cause the output to be sent to the printer. _ _ The +n option causes the output to start with page n. The _ _ -n option causes thThe appearance of a boldface command will cause any underlining to cease. .bp - causes succeeding text to appear at the top of a new page. The optional argument specifies the page number for the new page. The initial value is one and the default value is one more than the previous page number. .br - causes succeeding text to start on a new line at the -1- NRO (1) CP/M Version 2.2 NRO (1) current left margin. There is no numeric argument for this command. .bs - enables or disables the appearance of backspaces in the output text. Underlining and boldface options are implemented by inserting character - backspace - character combinations into the output buffer. This e output to stop after page n. _ The -v option prints the version number to the console. _ The -p option causes the output to be shifted to the right __ po by xx spaces. This has the same effect as the .po command. _ The -b option allows backspaces to appear in the output text when underlining or overstriking. This has the same effect bs as the .bs command with a non-zero argument. _ _____ The -m option processes the file mfile for macro definitions. Note that files processed in this way should is fine for devices which properly recognize the backspace character. Some printers, however, do not recognize backspaces, so the option is provided to overprint one line buffer with another. The first line buffer is terminated with just a carriage return rather than the carriage return - linefeed combination. A zero argument or no argument to the backspace command removes backspaces from the output. A non-zero argument leaves them in the output. The default is to remove backspaces. ___ .cc - changes the NRO command character to that specified by the character argument. If no argument is provided, the default is a period. .ce - causes the next line of text to appear centered on the outp contain only macro definitions, no immediate output should be generated from this file. Commands typically are distinguished by a period in column one of the input followed by a two character abbreviation for the command funtion. The abbreviation may then be followed by an optional numeric or character argument. The numeric argument may be an absolute value such as setting the right margin to a particular column, or the argument may be preceded by a plus sign or a minus sign to indicate that the parameter should be modified relative to a previous setting. The following commands are recognized: .bo - causes the following lines of text to appear in boldface. The optional argument specifies the number of lines to be typed in boldface. Boldface and underlining are mutually exclusive features. ut. The optional argument specifies if more than one line is to be centered. .de - causes all text and commands following to be used to en define a macro. The definition is terminated by a .en command. The first two characters of the argument de following the .de command become the name of the new command. It should be noted that upper and lower case arguments are considered different. Thus, the PP pp commands .PP and .pp could define two different macros. Care should be exercised since existing commands may be redefined. A macro may contain up to ten arguments. In the macro definition, the pl previously set left and right margins. No argument is expected. .fo - specifies text to be used for a footer. The footer text contains three strings seperated by a delimiter character. The first non-blank character following the command is designated as the delimiter. The first text string is left justified to the current in indentation value (specified by .in). The second string is centered between the current indentation value and the current right margin value (specified by rm .rm). The third string is right justified to the current right margin value. The absence of footer text will result in the footer being printed as one blanacement of arguments is designated by the two character sequences, $0, $1, ... $9. When the macro is invoked, each argument of the macro command line is substituted for its corresponding designator in the expansion. The first argument of the macro command is substituted for the $0 in the expansion, the second argument for the $1, and so forth. Arguments are typically strings which do not contain blanks or tabs. If an argument is to contain blanks, then it should be surrounded by either single or double quotes. .cu - causes the next line(s) of text to be continuously ul underlined. Unlike the underline command (see .ul) which underlines only alphanumerics, continuous underlining underlines all k line. The presence of the page number character pc (set by .pc) in the footer text results in the current page number being inserted at that position. Multiple occurrances of the page number character are allowed. .he - specifies text to be used for a header. The format is fo the same as for the footer (see .fo). .in - indents the left margin to the column value specified by the argument. The default left margin is set to zero. .ju - causes blanks to be inserted between words in a line of output in order to align or justify the right margin. The default is to justify. .ls - sets the line spacing to the value specified by the argument. The default is for singleprintable characters. The optional argument specifies the number of lines of text to underlined. Any normal underlining or boldface commands currently in effect will be terminated. -2- NRO (1) CP/M Version 2.2 NRO (1) .ef - specifies the text for the footer on even numbered pages. The format is the same as for the footer fo command (see .fo). .eh - specifies the text for the header on even numbered pages. The format is the same as for the footer fo command (see .fo). .en - designates the end of a macro definition. .fi - causes the input text to be rearranged or filled to obtain the maximum word count possible between the  spacing. .m1 - specifies the number of lines in the header margin. This is the space from the physical top of page to and including the header text. A value of zero causes the header to not be printed. A value of one causes the header to appear at the physical top of page. Larger argument values cause the appropriate number of blank lines to appear before the header is printed. .m2 - specifies the number of blank lines to be printed between the header line and the first line of the processed text. .m3 - specifies the number of blank lines to be printed -3- NRO (1) CP/M Version 2.2 NRO (1) between the last line of processed text and the footer line. .m4 - specifies the number ofk (#). .pl - specifies the page lenght or the number of lines per output page. The default is sixty-six. .po - specifies a page offset value. This allows the formatted text to be shifted to the right by the number of spaces specified. This feature may also be invoked by a switch on the command line. .rm - sets the column value for the right margin. The default is eighty. .so - causes input to be retrieved from the file specified by the command's character string argument. The contents of the new file are inserted into the output stream until an EOF is detected. Processing of the original file is then resumed. Command nesting is -4- NRO (1) CP/M Version 2.2 NRO (1) allowed.  lines in the footer margin. m1 This command affects the footer the same way the .m1 command affects the header. .ne - specifies a number of lines which should not be broken across a page boundary. If the number of lines remaining on a page is less than the value needed, then a new output page is started. .nf - specifies that succeeding text should be printed without rearrangement, or with no fill. No argument is expected. .nj - specifies that no attempt should be made to align or justify the right margin. No argument is expected. .nr - causes the value of a number register to be set or modified. A total of twenty-six number registers are available designated @na through @nz (either upper or  .sp - specifies a number of blank lines to be output before printing the next line of text. .ti - temporarily alters the indentation or left margin value for a single succeeding line of text. .ul - underlines the alphanumeric text in the following line(s). The optional argument specifies the number of lines to be underlined. Underlining and boldface are mutually exclusive features. The appearance of an underline command cancels any existing boldface operations. -5-  stream until an EOF is d/* * Parameter file for NRO word processor * * Stephen L. Browning * 5723 North Parker Avenue * Indianapolis, Indiana 46220 */ #define MACRO 0 /* macro definition */ #define BP 1 /* begin page */ #define BR 2 /* break */ #define CE 3  lower case is allowed). When the sequence @nc is imbedded in the text, the current value of number register c replaces the sequence, thus, such things as paragraph numbering can be accomplished with relative ease. .of - specifies the text for the footer on odd numbered pages. The format is the same as the footer command fo (see .fo). .oh - specifies the text for the header on odd numbered pages. The format is the same as the footer command fo (see .fo). .pc - specifies the page number character to be used in headers and footers. The occurrance of this character in the header or footer text results in the current page number being printed. The default for this character is the hash mar/* center */ #define FI 4 /* fill */ #define FO 5 /* footer */ #define HE 6 /* header */ #define IN 7 /* indent */ #define LS 8 /* line spacing */ #define NF 9 /* no fill */ #define PL 10 /* page lenght */ #define RM 11 /* right margin */ #define SP 12 /* line space */ #define TI 13 /* temp indent */ #define UL 14 /* underline */ #define JU 15 /* justify */ #define NJ 16 /* no justify */ #define M1 17 /* top margin */ #define M2 18 /* second top margin */ #define M3 19 /* first bottom margin */ #define M4 20 /* bottom-most margin */ #define BS 21 /* allow/disallow '\b' in output */ #define NE 22 /* need n lines */ #define PC 23 /* page number character */ #define CC 24 /* control character */ #define PO 25 /* page offset */ #define BO 26 /* bold face */ #define EH 27 /* header for even numbered pages */ #define OH 28 /* header for odd numbered pages */ #define EF 29 /* footer for even numbered pages */ #define OF 30 /* footer for odd numbered pages */ #define SO 31 /* sourcemb[MACBUF]; /* table of macro definitions */ char *ppb; /* pointer into push back buffer */ char pbb[MAXLINE]; /* push back buffer */ }; /* control parameters for nro */ struct docctl { int fill; /* fill if YES, init = YES */ int lsval; /* current line spacing, init = 1 */ int inval; /* current indent, >= 0, init = 0 */ int rmval; /* current right margin, init = 60 */ int tival; /* current temp indent, init = 0 */ int ceval; /* number of lines to center, init = 0 */ int ulval; /* number of lines to underline, init = 0 */ int cuval; /* no. lines to continuously underline, init = 0 */ int juval; /* justify if YES, init = YES */ int boval; /* number of lines to bold face, init = 0 */ int bsflg; /* can output contain '\b', init = FALSE */ char pgchr; /* page number character, init = '#' */ char cmdchr; /* command character, init = '.' */ int prflg; /* print on or off, init = TRUE */ int sprdir; /* direction for spread(), init = 0 */ int flevel; /* nesting depth for file */ #define CU 32 /* continuous underline */ #define DE 33 /* define macro */ #define EN 34 /* end macro definition */ #define NR 35 /* set number register */ #define UNKNOWN -1 /* * MAXLINE is set to a value slightly larger * than twice the longest expected input line. * Because of the way underlining is handled, the * input line which is to be underlined, can almost * triple in length. Unlike normal underlining and * boldfacing, continuous underlining affects all * characters in the buffer, and represents the * worst case condition. If the distance between * the left margin and the right margin is greater * than about 65 characters, and continuous underlining * is in effect, there is a high probability of buffer * overflow. */ #define MAXLINE 200 #define PAGELEN 66 #define PAGEWIDTH 80 #define HUGE 256 #define LEFT 0 /* indecies into header margin limit arrays */ #define RIGHT 1 #define NFILES 4 /* nesting depth for input files */ /* * The followin source cmd, init = 0 */ int nr[26]; /* number registers */ }; /* output buffer control parameters */ struct cout { int outp; /* next avail char position in outbuf, init = 0 */ int outw; /* width of text currently in buffer */ int outwds; /* number of words in buffer, init = 0 */ int lpr; /* output to printer, init = FALSE */ char outbuf[MAXLINE]; /* output of filled text */ }; /* page control parameters for nro */ struct page { int curpag; /* current output page number, init =0 */ int newpag; /* next output page number, init = 1 */ int lineno; /* next line to be printed, init = 0 */ int plval; /* page length in lines, init = 66 */ int m1val; /* margin before and including header */ int m2val; /* margin after header */ int m3val; /* margin after last text line */ int m4val; /* bottom margin, including footer */ int bottom; /* last live line on page = plval - m3val - m4val */ int offset; /* page offset from left, init = 0 */ int frstpg; /* first page tg parameters may be defined in bdscio.h */ #define YES 1 #define NO 0 #define ERR -1 /* * The parameter values selected for macro definitions * are somewhat arbitrary. MACBUF is the storage area * for both macro names and definitions. Since macro * processing is handled by pushing back the expansion * into the input buffer, the longest possible expansion * would be MAXLINE characters. Allowing for argument * expansion, MXMLEN was chosen slightly less than MAXLINE. * It is assumed that most macro definitions will not * exceed 20 characters, hence MXMDEF of 100. */ #define MXMDEF 100 /* maximum no. of macro definitions */ #define MACBUF 2000 /* macro definition buffer */ #define MXMLEN 150 /* maximum length of each macro definition */ #define MNLEN 10 /* maximum length of macro name */ struct macros { char *mnames[MXMDEF]; /* table of pointers to macro names */ int lastp; /* index to last mname */ char *emb; /* next char avail in macro defn buffer */ char o print, init = 0 */ int lastpg; /* last page to print, init = 30000 */ int ehlim[2]; /* left/right margins for headers/footers */ int ohlim[2]; /* init = 0 and PAGEWIDTH */ int eflim[2]; int oflim[2]; char ehead[MAXLINE]; /* top of page title, init = '\n' */ char ohead[MAXLINE]; char efoot[MAXLINE]; /* bottom of page title, init = '\n' */ char ofoot[MAXLINE]; }; char *getmac(); .TH NRO 1 "CP/M Version 2.2" .SH NAME nro - text processor .SH SYNOPSIS .bo nro [-n] [+n] [-pxx] [-v] [-b] [-mmfile] ifile ... [>ofile] .SH DESCRIPTION .ul NRO is a text processor and formatter based on the design provided in .bo "Software Tools" by Kernighan and Plauger. The text and commands found in the .cu ifile(s) are processed to generate formatted text. The output may be directed into a file or to the printer if .ul ofile is present in the command line; otherwise, the output wg text to start on a new line at the current left margin. There is no numeric argument for this command. !sp !ti -6 .bs - enables or disables the appearance of backspaces in the output text. Underlining and boldface options are implemented by inserting character - backspace - character combinations into the output buffer. This is fine for devices which properly recognize the backspace character. Some printers, however, do not recognize backspaces, so the option is provided to overprint one line buffer with another. The first line buffer is terminated with just a carriage return rather than the carriage return - linefeed combination. A zero argument or no argument to the backspace command removes backspaces from the output. A non-zero argument leaves them in the output. The default is to remove backspaces. !sp !ti -6 .cc - changes the !ul NRO command character to that specified by the character argument. If no argument is provided, the default is a period. !sp !ti -6 .ce - causes till appear at the user console. Directing the output to the special filename, .bo $P, will cause the output to be sent to the printer. .sp The .ul +n option causes the output to start with page .ul n. The .ul -n option causes the output to stop after page .ul n. .sp The .ul -v option prints the version number to the console. .sp The .ul -p option causes the output to be shifted to the right by .ul xx spaces. This has the same effect as the .cc + +bo .po command. +cc . .sp The .ul -b option allows backspaces to appear in the output text when underlining or overstriking. This has the same effect as the .cc + +bo .bs command with a non-zero argument. +cc . .sp The .ul -m option processes the file .ul mfile for macro definitions. Note that files processed in this way should contain only macro definitions, no immediate output should be generated from this file. .sp Commands typically are distinguished by a period in column one of the input followed by ahe next line of text to appear centered on the output. The optional argument specifies if more than one line is to be centered. !sp !ti -6 .de - causes all text and commands following to be used to define a macro. The definition is terminated by a !bo .en command. The first two characters of the argument following the !bo .de command become the name of the new command. It should be noted that upper and lower case arguments are considered different. Thus, the commands !bo .PP and !bo .pp could define two different macros. Care should be exercised since existing commands may be redefined. !sp A macro may contain up to ten arguments. In the macro definition, the placement of arguments is designated by the two character sequences, $0, $1, ... $9. When the macro is invoked, each argument of the macro command line is substituted for its corresponding designator in the expansion. The first argument of the macro command is substituted for the $0 in the expansion, the second argument for two character abbreviation for the command funtion. The abbreviation may then be followed by an optional numeric or character argument. The numeric argument may be an absolute value such as setting the right margin to a particular column, or the argument may be preceded by a plus sign or a minus sign to indicate that the parameter should be modified relative to a previous setting. The following commands are recognized: .sp .nj .in +6 .br .ti -6 .cc ! .bo - causes the following lines of text to appear in boldface. The optional argument specifies the number of lines to be typed in boldface. Boldface and underlining are mutually exclusive features. The appearance of a boldface command will cause any underlining to cease. !sp !ti -6 .bp - causes succeeding text to appear at the top of a new page. The optional argument specifies the page number for the new page. The initial value is one and the default value is one more than the previous page number. !sp !ti -6 .br - causes succeedin the $1, and so forth. Arguments are typically strings which do not contain blanks or tabs. If an argument is to contain blanks, then it should be surrounded by either single or double quotes. !sp !ti -6 .cu - causes the next line(s) of text to be continuously underlined. Unlike the underline command (see !bo .ul) which underlines only alphanumerics, continuous underlining underlines all printable characters. The optional argument specifies the number of lines of text to underlined. Any normal underlining or boldface commands currently in effect will be terminated. !sp !ti -6 .ef - specifies the text for the footer on even numbered pages. The format is the same as for the footer command (see !bo .fo). !sp !ti -6 .eh - specifies the text for the header on even numbered pages. The format is the same as for the footer command (see !bo .fo). !sp !ti -6 .en - designates the end of a macro definition. !sp !ti -6 .fi - causes the input text to be rearranged or filled to obtain the mto be printed between the last line of processed text and the footer line. !sp !ti -6 .m4 - specifies the number of lines in the footer margin. This command affects the footer the same way the !bo .m1 command affects the header. !sp !ti -6 .ne - specifies a number of lines which should not be broken across a page boundary. If the number of lines remaining on a page is less than the value needed, then a new output page is started. !sp !ti -6 .nf - specifies that succeeding text should be printed without rearrangement, or with no fill. No argument is expected. !sp !ti -6 .nj - specifies that no attempt should be made to align or justify the right margin. No argument is expected. !sp !ti -6 .nr - causes the value of a number register to be set or modified. A total of twenty-six number registers are available designated @@na through @@nz (either upper or lower case is allowed). When the sequence @@nc is imbedded in the text, the current value of number register c replaces the sequeaximum word count possible between the previously set left and right margins. No argument is expected. !sp !ti -6 .fo - specifies text to be used for a footer. The footer text contains three strings seperated by a delimiter character. The first non-blank character following the command is designated as the delimiter. The first text string is left justified to the current indentation value (specified by !bo .in). The second string is centered between the current indentation value and the current right margin value (specified by !bo .rm). The third string is right justified to the current right margin value. The absence of footer text will result in the footer being printed as one blank line. The presence of the page number character (set by !bo .pc) in the footer text results in the current page number being inserted at that position. Multiple occurrances of the page number character are allowed. !sp !ti -6 .he - specifies text to be used for a header. The format is the same as fonce, thus, such things as paragraph numbering can be accomplished with relative ease. !sp !ti -6 .of - specifies the text for the footer on odd numbered pages. The format is the same as the footer command (see !bo .fo). !sp !ti -6 .oh - specifies the text for the header on odd numbered pages. The format is the same as the footer command (see !bo .fo). !sp !ti -6 .pc - specifies the page number character to be used in headers and footers. The occurrance of this character in the header or footer text results in the current page number being printed. The default for this character is the hash mark (#). !sp !ti -6 .pl - specifies the page lenght or the number of lines per output page. The default is sixty-six. !sp !ti -6 .po - specifies a page offset value. This allows the formatted text to be shifted to the right by the number of spaces specified. This feature may also be invoked by a switch on the command line. !sp !ti -6 .rm - sets the column value for the right margin. The der the footer (see !bo .fo). !sp !ti -6 .in - indents the left margin to the column value specified by the argument. The default left margin is set to zero. !sp !ti -6 .ju - causes blanks to be inserted between words in a line of output in order to align or justify the right margin. The default is to justify. !sp !ti -6 .ls - sets the line spacing to the value specified by the argument. The default is for single spacing. !sp !ti -6 .m1 - specifies the number of lines in the header margin. This is the space from the physical top of page to and including the header text. A value of zero causes the header to not be printed. A value of one causes the header to appear at the physical top of page. Larger argument values cause the appropriate number of blank lines to appear before the header is printed. !sp !ti -6 .m2 - specifies the number of blank lines to be printed between the header line and the first line of the processed text. !sp !ti -6 .m3 - specifies the number of blank lines fault is eighty. !sp !ti -6 .so - causes input to be retrieved from the file specified by the command's character string argument. The contents of the new file are inserted into the output stream until an EOF is detected. Processing of the original file is then resumed. Command nesting is allowed. !sp !ti -6 .sp - specifies a number of blank lines to be output before printing the next line of text. !sp !ti -6 .ti - temporarily alters the indentation or left margin value for a single succeeding line of text. !sp !ti -6 .ul - underlines the alphanumeric text in the following line(s). The optional argument specifies the number of lines to be underlined. Underlining and boldface are mutually exclusive features. The appearance of an underline command cancels any existing boldface operations. /* * Command processor for NRO text processor * * Stephen L. Browning * 5723 North Parker Avenue * Indianapolis, India2val,val,argtyp,2,0,HUGE); break; case M3: /* set first bottom margin */ set(&pg.m3val,val,argtyp,2,0,HUGE); pg.bottom = pg.plval - pg.m4val - pg.m3val; break; case M4: /* set bottom-most margin */ set(&pg.m4val,val,argtyp,2,0,HUGE); pg.bottom = pg.plval - pg.m4val - pg.m3val; break; case MACRO: /* macro expansion */ maceval(p,macexp); break; case NE: /* need n lines */ brk(); if ((pg.bottom-pg.lineno+1) < (val*dc.lsval)) { space(HUGE); } break; case NF: /* no fill */ brk(); dc.fill = NO; break; case NJ: /* no justify */ dc.juval = NO; break; case NR: /* set number register */ p = skipwd(p); p = skipbl(p); if (!isalpha(*p)) { puts("***nro: invalid or missing number register name\n"); } else { index = tolower(*p) - 'a'; p = skipwd(p); val = getval(p,&argtyp); set(&dc.nr[index],val,argtyp,0,-HUGE,HUGE); } break; case OF: /* odd footer */ gettl(p,pg.ofoot,&pg.oflim[0]); break; case OH: /* odna 46220 */ #include "a:bdscio.h" #include "nro.h" #include "nrocom.c" comand(p) char *p; { int ct, val; int spval; int index; char argtyp; char name[MAXLINE]; char macexp[MXMLEN]; ct = comtyp(p,macexp); if (ct == UNKNOWN) { printf("*** nro: unrecognized command %s\n",p); return; } expesc(p,name); val = getval(p,&argtyp); switch (ct) { case BO: /* bold face */ set(&dc.boval,val,argtyp,1,0,HUGE); dc.cuval = dc.ulval = 0; break; case BP: /* begin page */ if(pg.lineno > 0) space(HUGE); set(&pg.curpag,val,argtyp,pg.curpag+1,-HUGE,HUGE); pg.newpag = pg.curpag; break; case BR: /* break */ brk(); break; case BS: /* backspaces in output */ set(&dc.bsflg,val,argtyp,1,0,1); break; case CC: /* command character */ if (argtyp == '\r' || argtyp == '\n') dc.cmdchr = '.'; else dc.cmdchr = argtyp; break; case CE: /* center */ brk(); set(&dc.ceval,val,argtyp,1,0,HUGE); break; case CU: /* continuous underline */ set(d header */ gettl(p,pg.ohead,&pg.ohlim[0]); break; case PC: /* page number character */ if (argtyp == '\r' || argtyp == '\n') dc.pgchr = EOS; else dc.pgchr = argtyp; break; case PL: /* page length */ set(&pg.plval,val,argtyp,PAGELEN, pg.m1val+pg.m2val+pg.m3val+pg.m4val+1,HUGE); pg.bottom = pg.plval - pg.m3val - pg.m4val; break; case PO: /* page offset */ set(&pg.offset,val,argtyp,0,0,HUGE); break; case RM: /* right margin */ set(&dc.rmval,val,argtyp,PAGEWIDTH,dc.tival+1,HUGE); break; case SO: /* source file */ p = skipwd(p); p = skipbl(p); if (getwrd(p,name) == 0) break; if (dc.flevel+1 >= NFILES) { puts("***nro: .so commands nested too deeply\n"); exit(-1); } if (fopen(name,&sofile[dc.flevel+1]) == ERR) { printf("***nro: unable to open %s\n",name); exit(-1); } ++dc.flevel; break; case SP: /* space */ set(&spval,val,argtyp,1,0,HUGE); space(spval); break; case TI: /* temporary indent */ brk(); set(&d&dc.cuval,val,argtyp,1,0,HUGE); dc.ulval = dc.boval = 0; break; case DE: /* define macro */ defmac(p,&sofile[dc.flevel]); break; case EF: /* even footer */ gettl(p,pg.efoot,&pg.eflim[0]); break; case EH: /* even header */ gettl(p,pg.ehead,&pg.ehlim[0]); break; case EN: /* end macro definition */ puts("***nro: missing .de command\n"); break; case FI: /* fill */ brk(); dc.fill = YES; break; case FO: /* footer */ gettl(p,pg.efoot,&pg.eflim[0]); gettl(p,pg.ofoot,&pg.oflim[0]); break; case HE: /* header */ gettl(p,pg.ehead,&pg.ehlim[0]); gettl(p,pg.ohead,&pg.ohlim[0]); break; case IN: /* indenting */ set(&dc.inval,val,argtyp,0,0,dc.rmval-1); dc.tival = dc.inval; break; case JU: /* justify */ dc.juval = YES; break; case LS: /* line spacing */ set(&dc.lsval,val,argtyp,1,1,HUGE); break; case M1: /* set topmost margin */ set(&pg.m1val,val,argtyp,2,0,HUGE); break; case M2: /* set second top margin */ set(&pg.mc.tival,val,argtyp,0,0,dc.rmval); break; case UL: /* underline */ set(&dc.ulval,val,argtyp,0,1,HUGE); dc.cuval = dc.boval = 0; break; } } /* * convert ascii character to decimal. */ atod(c) char c; { return(((c < '0') || (c > '9')) ? -1 : c-'0'); } /* * end current filled line */ brk() { if(co.outp > 0) { co.outbuf[co.outp] = '\r'; co.outbuf[co.outp + 1] = '\n'; co.outbuf[co.outp + 2] = EOS; put(co.outbuf); } co.outp = 0; co.outw = 0; co.outwds = 0; } /* * Collect macro definition from input stream */ colmac(p,d,i) char *p, d[]; int i; { while (*p != EOS) { if (i >= MXMLEN-1) { d[i-1] = EOS; return(ERR); } d[i++] = *p++; } d[i] = EOS; return(i); } /* * decodes nro command and returns its associated * value. */ comtyp(p,m) char *p; char *m; { char c1, c2; char macnam[MNLEN]; char *s; p++; /* * First check to see if the command is a macro. * If it is, truncate t d; } return(val); } /* * Define a macro */ defmac(p,infp) char *p; struct _buf *infp; { int i; char name[MNLEN]; char defn[MXMLEN]; char *q; q = skipwd(p); q = skipbl(q); i = getwrd(q,name); if (!isalpha(*name)) { puts("***nro: missing or illegal macro definition name\n"); exit(-1); } if (i > 2) name[2] = EOS; i = 0; while (getlin(p,infp) != EOF) { if (p[0] == dc.cmdchr && tolower(p[1]) == 'e' && tolower(p[2]) == 'n') { break; } if ((i = colmac(p,defn,i)) == ERR) { puts("***nro: macro definition too long\n"); exit(-1); } } if (putmac(name,defn) == ERR) { puts("***nro: macro definition table full\n"); exit(-1); } } /* * Expand escape sequences */ expesc(p,q) char *p; char *q; { char *s, *t; s = p; t = q; while (*s != EOS) { if (*s != '@') { *t++ = *s++; } else if (*(s+1) == '@') { *t++ = *s++; ++s; } else if (tolower(*(s+1)) == 'n' && isalpha(*(s+2))) { s += 2; to two characters and return * expansion in m. Note that upper and lower case * characters are handled differently for macro names, * but not for normal command names. */ getwrd(p,macnam); macnam[2] = EOS; if ((s = getmac(macnam)) != NULL) { strcpy(m,s); return(MACRO); } c1 = tolower(*p++); c2 = tolower(*p); if (c1 == 'b' && c2 == 'o') return(BO); if (c1 == 'b' && c2 == 'p') return(BP); if (c1 == 'b' && c2 == 'r') return(BR); if (c1 == 'b' && c2 == 's') return(BS); if (c1 == 'c' && c2 == 'c') return(CC); if (c1 == 'c' && c2 == 'e') return(CE); if (c1 == 'c' && c2 == 'u') return(CU); if (c1 == 'd' && c2 == 'e') return(DE); if (c1 == 'e' && c2 == 'f') return(EF); if (c1 == 'e' && c2 == 'h') return(EH); if (c1 == 'e' && c2 == 'n') return(EN); if (c1 == 'f' && c2 == 'i') return(FI); if (c1 == 'f' && c2 == 'o') return(FO); if (c1 == 'h' && c2 == 'e') return(HE); if (c1 == 'i' && c2 == 'n') return(IN); if (c1 == 'j' && c2 == 'u') return(JU); if (c1 == 'l'  += itoda(dc.nr[tolower(*s)-'a'],t,6) - 1; ++s; } else { *t++ = *s++; } } *t = EOS; strcpy(p,q); } /* * Get macro definition from table */ char *getmac(name) char *name; { int i; for (i = mac.lastp; i >= 0; --i) { if (!strcmp(name,mac.mnames[i])) { return(mac.mnames[i] + 3); } } return(NULL); } /* * get header or footer title */ gettl(p,q,limit) char *p; char *q; int limit[]; { p = skipwd(p); p = skipbl(p); strcpy(q,p); limit[LEFT] = dc.inval; limit[RIGHT] = dc.rmval; } /* * retrieves optional argument following nro command. * returns positive integer value with sign (if any) * saved in character addressed by p_argt. */ getval(p,p_argt) char *p; char *p_argt; { p = skipwd(p); p = skipbl(p); *p_argt = *p; if((*p == '+') || (*p == '-')) ++p; return(ctod(p)); } /* * Evaluate macro expansion */ maceval(p,m) char *p; char m[]; { int i, j; char *argp[10]; char c; *p++ && c2 == 's') return(LS); if (c1 == 'm' && c2 == '1') return(M1); if (c1 == 'm' && c2 == '2') return(M2); if (c1 == 'm' && c2 == '3') return(M3); if (c1 == 'm' && c2 == '4') return(M4); if (c1 == 'n' && c2 == 'e') return(NE); if (c1 == 'n' && c2 == 'f') return(NF); if (c1 == 'n' && c2 == 'j') return(NJ); if (c1 == 'n' && c2 == 'r') return(NR); if (c1 == 'o' && c2 == 'f') return(OF); if (c1 == 'o' && c2 == 'h') return(OH); if (c1 == 'p' && c2 == 'c') return(PC); if (c1 == 'p' && c2 == 'l') return(PL); if (c1 == 'p' && c2 == 'o') return(PO); if (c1 == 'r' && c2 == 'm') return(RM); if (c1 == 's' && c2 == 'o') return(SO); if (c1 == 's' && c2 == 'p') return(SP); if (c1 == 't' && c2 == 'i') return(TI); if (c1 == 'u' && c2 == 'l') return(UL); return(UNKNOWN); } /* * convert string to decimal. * processes only positive values. */ ctod(p) char *p; { int val, d; val = 0; while(*p != EOS) { d = atod(*p++); if(d == -1) return(val); val = 10 * val += EOS; /* replace command char with EOS */ /* * initialize argp array to substitute command * string for any undefined argument */ for (i=0; i<10; ++i) argp[i] = p; p = skipwd(p); *p++ = EOS; for (i=0; i<10; ++i) { p = skipbl(p); if (*p == '\r' || *p == '\n' || *p == EOS) break; if (*p == ''' || *p == '"') { c = *p++; argp[i] = p; while (*p != c && *p != '\r' && *p != '\n' && *p != EOS) ++p; *p++ = EOS; } else { argp[i] = p; p = skipwd(p); *p++ = EOS; } } for (i=strlen(m)-1; i>=0; --i) { if (i > 0 && m[i-1] == '$') { if (!isdigit(m[i])) { putbak(m[i]); } else { pbstr(argp[m[i]-'0']); --i; } } else { putbak(m[i]); } } } /* * Push back string into input stream */ pbstr(p) char p[]; { int i; for (i=strlen(p)-1; i>=0; --i) { putbak(p[i]); } } /* * Push character back into input stream */ putbak(c) char c; { if (mac.ppb < &mac.pbb[0]) { mac.ppb = &mac.pcc1 b:nro.c -o cc1 b:nrocmd.c -o cc1 b:nrotxt.c -o clink b:nro nrocmd nrotxt -s /* * Text processing portion of NRO word processor * * Stephen L. Browning * 5723 North Parker Avenue * Indianapolis, Indiana 46220 */ #include "a:bdscio.h" #include "nro.h" #include "nrocom.c" text(p) char *p; { int i; char wrdbuf[MAXLINE]; if (*p == ' ' || *p == '\n' || *p == '\r') leadbl(p); expesc(p,wrdbuf); if (dc.ulval > 0) { /* * Because of the way underlining is handled, * MAXLINE should be declared to be three times * larger than the longest expected input line * for underlining. Since many of the character * buffers use this parameter, a lot of memory * can be allocated when it may not really be * needed. A MAXLINE of 180 would allow about * 60 characters in the output line to be * underlined (remember that only alphanumerics * get underlined - no spaces or punctuation). */ underl(p,wrdbuf,MAXLINE); bb[0]; *mac.ppb = c; } else { if (mac.ppb >= &mac.pbb[MAXLINE-1]) { puts("***nro: push back buffer overflow\n"); exit(-1); } *++mac.ppb = c; } } /* * Put macro definition into table */ putmac(name,p) char *name; char *p; { if (mac.lastp >= MXMDEF) return(ERR); if (mac.emb + strlen(name) + strlen(p) + 1 > &mac.mb[MACBUF]) { return(ERR); } ++mac.lastp; mac.mnames[mac.lastp] = mac.emb; strcpy(mac.emb,name); strcpy(mac.emb + strlen(name) + 1,p); mac.emb += strlen(name) + strlen(p) + 2; return(OK); } /* * set parameter and check range */ set(param,val,type,defval,minval,maxval) int *param; int val; char type; int defval,minval,maxval; { switch(type) { case '\r': case '\n': *param = defval; break; case '+': *param += val; break; case '-': *param -= val; break; default: *param = val; break; } *param = min(*param,maxval); *param = max(*param,minval); } /* * skip blanks and tabs  --dc.ulval; } if (dc.cuval > 0) { underl(p,wrdbuf,MAXLINE); --dc.cuval; } if (dc.boval > 0) { bold(p,wrdbuf,MAXLINE); --dc.boval; } if (dc.ceval > 0) { center(p); put(p); --dc.ceval; } else if (*p == '\r' || *p == '\n') put(p); /* all blank line */ else if (dc.fill == NO) put(p); /* unfilled */ else { while ((i = getwrd(p,wrdbuf)) > 0) { putwrd(wrdbuf); p += i; } } } /* * insert bold face text */ bold(p0,p1,size) char *p0, *p1; int size; { int i, j; j = 0; for (i=0; (p0[i] != '\n') && (j < size-1); ++i) { if (isalpha(p0[i]) || isdigit(p0[i])) { p1[j++] = p0[i]; p1[j++] = '\b'; } p1[j++] = p0[i]; } p1[j++] = '\n'; p1[j] = EOS; while (*p1 != EOS) *p0++ = *p1++; *p0 = EOS; } /* * center a line by setting tival */ center(p) char *p; { dc.tival = max((dc.rmval + dc.tival - width(p)) >> 1,0); } /* * expand title buffer to include character string */ expand(p0,c,s) char *in character buffer. * return number of characters skipped. */ char *skipbl(p) char *p; { while (*p == ' ' || *p == '\t') ++p; return(p); } /* * skip over word and punctuation */ char *skipwd(p) char *p; { while (*p != ' ' && *p != '\t' && *p != '\r' && *p != '\n' && *p != EOS) ++p; return(p); } /* * space vertically n lines */ space(n) int n; { brk(); if (pg.lineno > pg.bottom) return; if (pg.lineno == 0) phead(); skip(min(n,pg.bottom+1-pg.lineno)); pg.lineno += n; if (pg.lineno > pg.bottom) pfoot(); } /* * external "common" for NRO word processor * * Stephen L. Browning * 5723 North Parker Avenue * Indianapolis, Indiana 46220 */ struct docctl dc; struct page pg; struct _buf oub; struct _buf *pout; struct cout co; struct _buf sofile[NFILES]; /* input file buffers */ struct macros mac; p0; char c; char *s; { char tmp[MAXLINE]; char *p, *q, *r; p = p0; q = tmp; while (*p != EOS) { if (*p == c) { r = s; while (*r != EOS) *q++ = *r++; } else *q++ = *p; ++p; } *q = EOS; strcpy(p0,tmp); /* copy it back */ } /* * get field from title */ char *getfield(p,q,delim) char *p, *q; char delim; { while (*p != delim && *p != '\r' && *p != '\n' && *p != EOS) { *q++ = *p++; } *q = EOS; if (*p == delim) ++p; return(p); } /* * get non-blank word from p0 into p1. * return number of characters processed. */ getwrd(p0,p1) char *p0,*p1; { int i; char *p, c; i = 0; while (*p0 == ' ' || *p0 == '\t') { ++i; ++p0; } p = p0; while (*p0 != ' ' && *p0 != EOS && *p0 != '\t') { if (*p0 == '\n' || *p0 == '\r') break; *p1 = *p0++; ++p1; ++i; } c = *(p1-1); if (c == '"') c = *(p1-2); if (c == '?' || c == '!') { *p1++ = ' '; ++i; } if (c == '.' && (*p0 == '\n' || *p0 == '\r' || islower( (pg.m1val > 0) { skip(pg.m1val - 1); if ((pg.curpag % 2) == 0) { puttl(pg.ehead,pg.ehlim,pg.curpag); } else { puttl(pg.ohead,pg.ohlim,pg.curpag); } } skip(pg.m2val); } /* * initialize lineno for the next page */ pg.lineno = pg.m1val + pg.m2val + 1; } /* * print character with test for printer */ prchar(c,fp) char c; struct _buf *fp; { if (co.lpr == TRUE) { bdos(5,c); } else { putc(c,fp); } } /* * put out line with proper spacing and indenting */ put(p) char *p; { char os[MAXLINE]; int j; if (pg.lineno == 0 || pg.lineno > pg.bottom) { phead(); } if (dc.prflg == TRUE) { if (!dc.bsflg) { if (strkovr(p,os) == TRUE) { for (j=0; j 0 && i <= size); if (value < 0 && i <= size) c[i++] = '-'; for (j=0; j> 1]; while (*p != EOS) *q++ = *p++; } /* * left justify title text into print buffer */ justleft(p,q,limit) char *p, *q; int limit; { q = &q[limit]; while (*p != EOS) *q++ = *p++; } /* * right justify title text into print buffer */ justrite(p,q,limit) char *p, *q; int limit; { int len; len = width(p); q = &q[limit - len]; while (*p !in(dc.lsval-1,pg.bottom-pg.lineno)); pg.lineno = pg.lineno + dc.lsval; if (pg.lineno > pg.bottom) pfoot(); } /* * output a null terminated string to the file * specified by pbuf. */ putlin(p,pbuf) char *p; struct buf *pbuf; { while (*p != EOS) prchar(*p++,pbuf); } /* * put out title or footer */ puttl(p,lim,pgno) char *p; int lim[]; int pgno; { int i; char pn[8]; char t[MAXLINE]; char h[MAXLINE]; char delim; itoda(pgno,pn,6); for (i=0; i 2) { for (i=0; i v2) ? v1 : v2); } /* * put out page footer */ pfoot() { if (dc.prflg == TRUE) { skip(pg.m3val); if (pg.m4val > 0) { if ((pg.curpag % 2) == 0) { puttl(pg.efoot,pg.eflim,pg.curpag); } else { puttl(pg.ofoot,pg.oflim,pg.curpag); } skip(pg.m4val - 1); } } } /* * put out page header */ phead() { pg.curpag = pg.newpag; if (pg.curpag >= pg.frstpg && pg.curpag <= pg.lastpg) { dc.prflg = TRUE; } else { dc.prflg = FALSE; } ++pg.newpag; if (dc.prflg == TRUE) { ifrd(wrdbuf) char *wrdbuf; { int w; int last; int llval; char *p0, *p1; int nextra; w = width(wrdbuf); last = strlen(wrdbuf) + co.outp; llval = dc.rmval - dc.tival; if(((co.outp > 0) && ((co.outw + w) > llval)) || (last > MAXLINE)) { last -= co.outp; if(dc.juval == YES) { nextra = llval - co.outw + 1; /* * Check whether last word was end of * sentence and modify counts so that * it is right justified. */ if (co.outbuf[co.outp-2] == ' ') { --co.outp; ++nextra; } spread(co.outbuf,co.outp-1,nextra,co.outwds); if((nextra > 0) && (co.outwds > 1)) { co.outp += (nextra - 1); } } brk(); } p0 = wrdbuf; p1 = co.outbuf + co.outp; while(*p0 != EOS) *p1++ = *p0++; co.outp = last; co.outbuf[co.outp++] = ' '; co.outw += w + 1; ++co.outwds; } /* * skips the number of lines specified by n. */ skip(n) int n; { int i; if (dc.prflg == TRUE && n > 0) { for(i=0; i0; --nb) { --j; p[j] = ' '; } } --i; --j; } } /* * split overstrikes (backspaces) into seperate buffer */ strkovr(p,q) char *p, *q; { char *pp; int bsflg; bsflg = FALSE; pp = p; while (*p != EOS) { *q = ' '; *pp = *p; ++p; if (*p == '\b') { if (*pp >= ' ' && *pp <= '~') { bsflg = TRUE; *q = *pp; ++p; *pp = *p; ++p; } }  README 1ST VIXLABL1COM VIXLABL1DOC)VIXLABL1ASMD Dear Mr. McKay: Pursuant to your request that we submit any public domain software that we might have adapted to the Vixen, the accompanying programs may be of interest. They are named VIXLABL1.ASM, VIXLABL1.COM AND VIXLABL1.DOC respectively and represent a somewhat revised version of Dennis McFerran's DSKLABl programs. The revision was made to serve two purposes that are somewhat unique to the Vixen. First, the size of the drives means that the number of files kept on one disk will generally be greater than on the O1 and Exec with single-sided drives. Second, the drive space calculation requires recognition of the ++q; ++pp; } *q++ = '\r'; *q = *pp = EOS; return(bsflg); } /* * underline a line */ underl(p0,p1,size) char *p0,*p1; int size; { int i,j; j = 0; for (i=0; (p0[i] != '\n') && (j < size-1); ++i) { if (p0[i] >= ' ' && p0[i] <= '~') { if (isalpha(p0[i]) || isdigit(p0[i]) || dc.cuval > 0) { p1[j++] = '_'; p1[j++] = '\b'; } } p1[j++] = p0[i]; } p1[j++] = '\n'; p1[j] = EOS; while (*p1 != EOS) *p0++ = *p1++; *p0 = EOS; } /* * compute width of character string */ width(s) char *s; { int w; w = 0; while (*s != EOS) { if (*s == '\b') --w; else if (*s != '\n' && *s != '\r') ++w; ++s; } return(w); } .TH SKELETON 1 "New Manual Name" .SH NAME skeleton - sample manual page .SH SYNOPSIS .bo skeleton [options] .SH DESCRIPTION This section describes the program or file. .SH CAVEATS .SH EXAMPLES Just what the name implies. .SH FILES an.nro .SH  double-sided drive. This revision squeezes more file names onto a 3.5 x 1 label by using the superscript (tiny) print on the Epson RX-80 (and, I think, several other printers). The Free Space calculation is also changed. The .DOC file explains the program use which parallels that of DSKLABL.COM. I hope these may be of some value to someone. John Krahmer (806) 794-5323 h parallels that of DSKLABL.COM. I hope these may be of some value to someone. John Krahmer !9"Y1Y :m2[!] 6?#d9ͮͷ [!~ҵ#~2ҵ#~ҵ!~p>12j~02k#~0ڇ>32m~0æ~ ژ>22m~ æ~ڦ>12m~02n#~ր02q>$2>2  !9##~0G''''O#~0' \>-2]&< \&x<Input disk name (max 7 filename, 3 extension) (ie UTILITY.001) A dash (-) will be added automatically at the beginning of the filename and a period will be inserted before the extension. The name will be written this revision, each label can contain one (1) header line and up to twelve (12) disk directory lines for a total of 48 filenames. I have tried to document the source code so others can easily adjust the printer codes and the line spacings to match other printers or label sizes (on a two inch x 3.5 inch label, up to 100 filenames could be printed). The easiest way to use the program is to put it on a disk in the A: drive and type VIXLABL1 B: to generate labels for disks inserted, one by one, into the B: drive. In my own use of the program, I have found it easier to do a number of labels at one time because of the need to set up the printer with label stock. The program will look for a file name on User 15 to use as the disk name in the label header line. By convention, the name should have a dash (-) as the first character so the sorting routine will select it as the first entry. If a filename is found, the program will print a label (assuming you turned on your printer). If there is o the disk in User Area 15 and will appear in the heading of the label. Disk Name? ===> )-------|---($ %  †k  ]!m>-#\ *.|g" *.*.>w*.|w*w# xn VIXLABL1 B:~A` #!o> V>.V~ ^#V:\2^2]:^=2]:]_"_~ ک!\6!t6D#6S#6D#6D*_^#V#"a*_##~2e!)=*a:]_+0#~*f#"fz :]O{_zW {oz(>O:]A:e*f=;)0:\D)R{$>k*hw [ |R{0*hw#"h~#$ʉ͋|_ :<2!j#!#à>?!]w\<2 \<=!o*w#":<2:!s#r# =:2 2 =[2: =22 [!##:=2A:-!">82>2  =*^#V#"1>.1: =2 : =2 ¯>2 õ! #:=2k>82͙k   !#*Y^#V#N#F #currently no name in User 15, the program will prompt you for a name and write the name you supply in that user area before going ahead with label printing. If you later need to change or erase the name, you will need to go to user 15 to do so as it will not show up in the default user 0 area. You can get to user 15 either by typing "user 15" at the A prompt or B prompt and use the CPM rename command "ren" or erase command "era". You can also use the NSWP205.COM (or later versions) to get to this user area. In either case, be sure to go back to user 0 before continuing (and don't be afraid you erased your entire disk if you do a "DIR" command while in user 15 and don't see any files--that will only mean there are no files in that user area. If you type "user 0" you will see that your other files are still there. (If this is vague, take a look at the Vixen manual or a CPM book on the subject of user areas.) If you simply type in the name VIXLABL1, the program assumes that you want to gen>2N#F#^q#Vpr+s_>$~##~#1[!##:=2A:-! / /8 SngD Free Space= Page 0 $Please enter today's date as mm/dd/yy---->$  A CBU$CAUS0CUS0$ | $ Documentation for VIXLABL1.COM This program is a revision of the DSKLABL.COM programs by Dennis McFerran. The revision is by John Krahmer. Addresses for both persons are in the VIXLABL1.ASM source code file. One purpose of the revision is to adjust the calculation of the free space on double-sided Vixen disks (as opposed to the single-sided disks on the single and double density O1 and Exec). Another pupose of the revision is to permit more file names to be squeezed on a 1 inch x 3.5 inch Avery label by using the superscript mode available on the Epson RX-80 printer and on some other printers. As set in terate a label for the disk in drive A: Usage hints: The Vixen special function key allows the user to easily program a function key to save the nuisance of typing the awkward program name over and over again. I just set up ^1 to say VIXLABL1 B:^M and flip disks in and out of Drive B: as fast as the labels are generated. Another hint is to be careful when choosing a name for the disk and typing it in at the prompt line. Some thought about how you want to organize your disks is worthwhile. For example, you might want to have a series labeled "UTILITY.001, UTILITY.002", etc. and another series labeled "MATH.001, MATH.002",etc. It saves some time to plan this in advance to avoid redoing labels. The program is preset to insert a dash (-) in front of the filename (as in -UTILITY) so you only have seven characters instead of eight for the filename. The program also automatically inserts a period before the characters that appear in the extension so you don't have to type the period when you cation runs on an Epson ; RX-80 and may work on an Epson MX-80 with Graphtrax. ; ; ;Program name: DSKLABL ;Version : 1 ;Purpose : Prepare a printed "Avery" type label ; to identify the various files on a ; disk. ;Equipment : Written for the Osborne 01 and modified for the Osborne 04 Vixen ; with Double Sided Double Density Drives and the Epson ; Printer ; ;Output : The program produces a label with a ; heading that shows: ; a) The date produced ; b) The amount of Free Space on the disk ; c) The "Name" of the disk (i.e. -UTILITY.U01) ; d) The "Page" number of the label relative ; to that particular disk ; ;Instructions: ; 1. Place this program on a disk in ; Drive A. It makes some sense to ; include it on the same disk that you ; use for cataloging your files (NCAT ; or whatever). If you don't catalog ; I suggesenter a filename and extension. Be sure to type any extension to the right of the vertical line (|) that appears in the prompt as the program only reads those characters to determine the extension. If you use fewer than seven characters for the filename, just space over past the line (|) to type the extension. The reverse video on the Vixen makes the prompt look a little odd because the cursor sitting over the first character of the prompt blanks the reverse video (ie, reverse video on the cursor overlays the reverse video on the prompt). Just ignore this and start typing the filename. One other suggestion. If you change the program name, you should make a conforming change in the VIXLABL1.ASM file so the program can find itself after asking for a filename. After a filename is supplied, the program goes back to user 0 to look for "VIXLABL1" and, if it is not there (as when the name has been changed), it will abort. No harm will be done, but you will have to restart the program at the Ct that you check out the ; possiblities in the FOG library. ; ; 2. Put the continuous form labels in ; your printer. ; ; 3. Mount the disk to be labeled in ; drive B. ; ; 4. Type dsklabl1 b: ; ; 5. The first time in each labelling session ; the program will ask you for the date. It ; is stored so that it will be remembered ; from disk to disk unless you depress the RESET ; button. ; ; 6. The disk will whir for a second and then, ; assuming you have turned on your printer, ; will produce a label(s) that you may affix ; to the disk. ; ; 7. Repeat step 4 for each disk that you want ; to label. ; ;Remarks [by McFerran]: This is the first version of a nearly complete ; rewrite of my old DIRLABLE program and solves many problems ; that were inherent in that code. ; This program now (I hope) calculates the Free Space on the ; disk properly, allows the user to easilPM command line. This can be a nuisance. The name appears about one-half way through the .ASM file and I have included a comment line to identify it. Once changed, you will need to re-assemble and re-load the program under the new name you have chosen. There are no warranties, express or implied, on the program and it is supplied AS IS for distribution in the public domain.  There are no warranties, express or implied, on the program and it is supplied AS IS for distribution in the public doma; The following software is copyrighted 10/20/83 by: ; Dennis McFerran ; 1038 Polk Lane ; San Jose, CA 95117 ; Tel-408-296-6021 ; Comments and suggestions welcome. ; This software modified 06/04/85 by: ; John Krahmer ; 4901 77th Street ; Lubbock, TX 79409 ; Tel-806-794-5323 ; Purpose of Modification: To use superscript size print on disk labels ; for the Osborne 4 Vixen which has 390k drives. The modification ; squeezes more file names on a label. The modifiy change the number ; of columns and lines of information to fit any size of ; label that you want to use, identifies the "name" of the ; disk on each "Page" of labels that it creates for the disk. ; ;Remarks [by Krahmer]: This program seems to do everything Dennis ; McFerran hoped for. The printer, spacing and line modifications I have ; added are trivial by comparison. The only other adjustment was a change ; for the calculation of remaining disk space. I am not enough of an ; assembly language programmer to know if the change is correct for all ; cases, but it seems to work properly on the double sided double density ; disks I have tried. The change is noted in the source code. ; ;===The following will determine the number of columns ; and lines that will appear on your label. The ; current values of 4 and 14 will fit on a standard ; 3.5" by 15/16" label. LINEMAX EQU 4 ;For 4 across labeling LINES EQU 14 ;For 12 lines of listing plus heear mvi a,'1' sta datstor+3 mov a,m sui 10h getyear adi 30h sta datstor+4 inx h mov a,m sui 80h adi 30h sta datstor+7 ret GETDATE: MVI A,'$' STA TEMPBUFF+10 MVI A,8 STA TEMPBUFF LXI D,DATEREQ MVI C,PRINT CALL BDOS MVI C,RDCON LXI D,TEMPBUFF CALL BDOS lxi d,datebuff lxi h,tempbuff call convert call convert call convert jmp SETDATE convert inx h inx h mov a,m sui 30h mov b,a add a daa add a daa add b daa add a daa mov c,a inx h mov a,m sui 30h add c daa stax d inx d ret GETDISK: MVI E,15 MVI C,32 CALL BDOS LXI d,fcb MVI a,'-' STA fcb+1 MVI C,17 CALL FINDFILE JP Foundit MVI E,00 MVI C,32 CALL BDOS LXI d,fcb MVI C,17 CALL FINDFILE JM Noname JMP Foundit ;===error routine diskreq db 1ah,'Input disk name (max 7 filename, 3 extension)',cr,lf ader per label ; ;**********EPSON RX-80 PRINTER CODES*************** ;===These codes must be changed for other printers * ; * ESCAPE EQU 27 ; * SPACING EQU 65 ;LINE SPACING * COLSET EQU 15 ;SET FOR 132 COLUMNS CONDON1 EQU 83 ;SUPERSCRIPT PRINTING ON I.* CONDON2 EQU 48 ;SUPERSCRIPT PRINTING ON II. * UNIDIR EQU 'U' ;UNIDIRECTIONAL PRINT * FORLEN EQU 67 ;SETS FORM LENGTH * FORMFEED EQU 12 ;FORM FEED * CR EQU 13 ;CARRIAGE RETURN * LF EQU 10 ;LINE FEED * ;*************************************************** ; ; ; ORG 100h ;*************************************************** ;STARTUP OPERATIONS STARTUP LXI H,0 ;SAVE THE OLD STACK DAD SP ;H=STACK SHLD STACK ;SAVE IT LXI SP,STACK ;GET NEW STACK ;RESET SYSTEM reset MVI C,13 CALL BDOS ;SAVE FILE WRITE REQUEST CHAR LDA FCB+17 STA FILESW LXI H,FCB+1 ;MAKE FCB ALL '?' MVI B,11 ;FN+FT C db '(ie UTILITY.001) A dash (-) will be added automatically',cr,lf db 'at the beginning of the filename and a period will be',cr,lf db 'inserted before the extension. The name will be written',cr,lf db 'to the disk in User Area 15 and will appear in the ',cr,lf db 'heading of the label.',cr,lf db 'Disk Name? ===> ' nameform db 1bh,29h,'-------|---',1bh,28h,'$' consbuff db 11,00,' ' noname lxi d,diskreq mvi c,print call bdos mvi b,11 mvi c,02 mvi e,08 backmor push d push b call bdos pop b dcr b pop d jnz backmor lxi d,consbuff mvi c,10 call bdos mvi c,32 mvi e,15 call bdos lxi d,fcb+1 lxi h,consbuff+2 mvi a,'-' stax d inx d mvi b,7 call movmor mvi b,3 inx h call movmor mvi c,22 lxi d,fcb call bdos mvi c,32 mvi e,00 call bdos restart lhld 01 mvi l,00 mov a,h sui 16h mov h,a shld ccp lxi d,refile lxi b,10 lhld ccp mvi l,07 call again lhld ccp OUNT QLOOP MVI M,'?' ;STORE '?' IN FCB INX H DCR B JNZ QLOOP ;*************************************************** HEADER: call getspace call setdate call getdisk call initptr call findfiles call sorter call printit jmp 0000 SETDATE: lxi h,datebuff mov a,m cpi 1h ;is month 1-12 jm getdate cpi 13h jnc getdate inx h mov a,m cpi 1h ;is day 1-31 jm getdate cpi 32h jnc getdate inx h mov a,m cpi 80h ;is year 80-89 jm getdate cpi 90h jnc getdate ;if so date is ok as is MONTH lxi h,0010h mov a,m cpi 10h jc lessten mvi a,'1' sta datstor mov a,m sui 10h lessten adi 30h sta datstor+1 DAY inx h mov a,m cpi 30h jc lessthrty mvi a,'3' sta datstor+3 mov a,m sui 30h jmp getyear lessthrty mov a,m cpi 20h jc lesstwnty mvi a,'2' sta datstor+3 mov a,m sui 20h jmp getyear lesstwnty mov a,m cpi 10h jc gety mvi l,88h mvi a,08h mov m,a lhld ccp mvi l,89h mov a,h mov m,a lhld ccp pchl again ldax d mov m,a inx h inx d dcx b mov a,b ora c jnz again ret ccp ds 2 ;Change the filename in the next line if you rename the program refile db 10,'VIXLABL1 B:',0,0,0,0,0,0,0 movmor mov a,m cpi 'A' jc okasis cpi 'a'-1 jc okasis sui 20h okasis stax d inx h inx d dcr b jnz movmor ret FINDFILE CALL BDOS ORA A RM ANI 3 ;make mod 4 ADD A ;mult ADD A ; by ADD A ; 32 ADD A ; for ADD A ; offset LXI H,81h ADD L ;Point to entry MOV L,A ;h-l now addresses filename mvi a,0 adi 1h RET Foundit push h MVI E,00 MVI C,32 CALL BDOS POP h lxi d,DISKSTOR MVI b,8 CALL Morstor mvi a,'.' stax d inx d mvi b,3 jmp Morstor ;jump and return MORSTOR MOV a,m cpi ' ' jz skipsp stax d inx d skiret l13f xthl l140 mov a,m inx h cpi 24h jz l14d call l14f jmp l140 l14d xthl ret l14f push h push d push b push psw mvi c,02 ani 7fh mov e,a pop psw pop b pop d pop h ret EJECT: mvi e,12 mvi c,wrchr call bdos PRINTHEAD: lda pagestor inr a sta pagestor lxi h,datstor call wrcon ret ;Initialize printer INITPTR LXI H,TTL ;printer initialization Call wrcon Jmp Printhead ;FIND FILES; SORT; and PRINT FINDFILES: mvi a,'?' lxi h,005dh mov m,a MVI C,FSRCHF ;GET 'SEARCH FIRST' FNC LXI D,FCB CALL BDOS ;READ FIRST INR A ;WERE THERE ANY? STA TEMP ;SAVE JZ EXIT1 ;GOT SOME - PRT TITLE, CONT CALL SOME MVI E,00 MVI C,32 CALL BDOS RET ;READ MORE DIRECTORY ENTRIES MOREDIR MVI C,FSRCHN ;SEARCH NEXT LXI D,FCB CALL BDOS ;READ DIR ENTRY INR A ;CHECK FOR END (0FFH) RZ ;GOTFCB1 ;NO MORE - SORT & PRINT ;POINT TO DIRECTORY ENTRY SOME DCR A ;UNDO PREV 'INR A' ANI 3 ;Mpsp inx h dcr b jnz morstor Ret GETSPACE: lda 005ch sta l389 push psw ;call ddorsd pop psw mvi c,19h call 0005 sta l388 lda l389 ora a jz l21f dcr a sta l388 l21f lda l388 mvi c,0eh mov e,a call 0005 mvi c,1fh call 0005 shld l38a MOV A,M ;IF ITS 28 ITS DD ;IF ITS 14 ITS SD CPI 20H jc single DOUBLE LXI H,EXTVAL ;The next line originally read MVI M,1 and needed to be changed to ;reflect the double-sided Vixen drives. It seems to work properly. MVI M,2 lxi h,DENSITY Mvi m,'D' inx h Mvi m,'S' inx h Mvi m,'D' inx h Mvi m,'D' single lhld l38a lxi d,0005 dad d mov e,m inx h mov d,m xchg inx h shld l38c lhld l38a inx h inx h mov a,m sui 02 sta l380 lxi h,0200h l277 dad h dcr a lhld l38c push h lda l388 mov e,a mvi c,0eh ;select disk call 0005 mvi c,1bh call 0005 pop d dcx h l2a9 mvi c,30h l2ae inx h AKE MODULUS 4 ADD A ;MULTIPLY... ADD A ;..BY 32 BECAUSE ADD A ;..EACH DIRECTORY ADD A ;..ENTRY IS 32 ADD A ;..BYTES LONG LXI H,81H ;POINT TO BUFFER ;(SKIP TO FN/FT) ADD L ;POINT TO ENTRY MOV L,A ;SAVE (CAN'T CARRY TO H) ;MOVE ENTRY TO TABLE XCHG ;ENTRY TO DE LHLD NEXTT ;NEXT TABLE ENTRY TO HL MVI B,31 ;ENTRY LENGTH TMOVE LDAX D ;GET ENTRY CHAR MOV M,A ;STORE IN TABLE INX D INX H DCR B ;MORE? JNZ TMOVE SHLD NEXTT ;SAVE UPDATED TABLE ADDR LDA COUNT ;GET PREV COUNT INR A STA COUNT JMP MOREDIR ;SORT AND PRINT sorter LDA COUNT ;INIT THE ORDER TABLE LXI H,ORDER LXI D,TABLE LXI B,31 ;ENTRY LENGTH BLDORD MOV M,E ;SAVE LO ORD ADDR INX H MOV M,D ;SAVE HI ORD ADDR INX H XCHG ;TABLE ADDR TO HL DAD B ;POINT TO NEXT ENTRY XCHG DCR A ;MORE? JNZ BLDORD ;..YES LDA COUNT ;GET COUNT STA FILCOUNT;SAVE AS # TO PRINT STA SCOUNT ;SAVE AS # TO SORT DCR A ;ONLY 1 ENTRY? JZ Printit ;.YES, SO SKIP SORT SORT XRA A ;GET A ZERO STA SWITCH ;SHOW NONE S mov a,m mvi b,08h l2b2 rlc jc past push h lhld l381 inx h shld l381 pop h past dcx d push psw mov a,d ora e jz l2cc pop psw dcr c jz l2a9 dcr b jz l2ae jmp l2b2 l2cc pop psw mvi c,1dh call 0005 lda l388 lxi d,0001 ora a mov c,a l2e0 jz l2ed mov a,e rlc mov e,a mov a,d rlc mov d,a dcr c jmp l2e0 l2ed mov a,e ana l mov l,a mov a,d ana h ora l jz l2fb mvi a,4fh l2fb lda l388 adi 41h lda l380 l31b lhld l381 dcr a jz l323 dad h jmp l31b l323 lda extval cpi 1 jz dbld dad h dbld call l183 call l13f db '$' mvi a,'k' lhld storaddr mov m,a ret l183 push b push d push h lxi b,0fff6h lxi d,0ffffh l18c dad b inx d jc l18c lxi b,000ah dad b xchg mov a,h ora l cnz l183 mov a,e adi 30h push h lhld storaddr mov m,a inx h shld storaddr pop h pop h pop d pop b WITCHED LDA SCOUNT ;GET COUNT DCR A ;USE 1 LESS STA TEMP ;SAVE # TO COMPARE STA SCOUNT ;SAVE HIGHEST ENTRY JZ Printit ;EXIT IF NO MORE LXI H,ORDER ;POINT TO ORDER TABLE SORTLP CALL COMPR ;COMPARE 2 ENTRIES CM SWAP ;SWAP IF NOT IN ORDER INX H ;BUMP ORDER INX H ;..TABLE POINTER LDA TEMP ;GET COUNT DCR A STA TEMP JNZ SORTLP ;CONTINUE ;ONE PASS OF SORT DONE LDA SWITCH ;ANY SWAPS DONE? ORA A JNZ SORT ;SORT IS ALL DONE - PRINT ENTRIES RET printit LXI H,ORDER SHLD NEXTT MVI A,labelmax ;entries on one label STA LabCount MVI A,linemax ;entries on one line STA PrCount ;PRINT AN ENTRY ENTRY MVI C,CONST ;CK STATUS OF KB CALL BDOS ;ANY KEY PRESSED? DCR A JZ ABORT ;YES, ABORT LHLD NEXTT ;GET ORDER TABLE POINTER MOV E,M ;GET LO ADDR INX H MOV D,M ;GET HI ADDR INX H SHLD NEXTT ;SAVE UPDATED TABLE POINTER XCHG ;TABLE ENTRY TO HL MVI B,8 ;FILE NAME LENGTH CALL TYPEIT ;TYPE FILENAME MVI A,'.' CALL TYPE MVI B,3 ;GET THE FILETYPE 8 ' DENSITY db 'SngD Free Space=' SPACSTOR db 00,00,00 db ' ' DISKSTOR db ' Page ' PAGESTOR db '0',cr,lf,'$' DATEREQ DB 'Please enter today''s date as mm/dd/yy---->$' FCB EQU 005CH ;file control block BDOS EQU 0005H ;BDOS CALL LOCATION DATEBUFF EQU 0010H PRINT EQU 9 ;PRINT CONSOLE BUFF RDCON EQU 10 ;READ CONS BUFFER WRCHR EQU 5 RDCHR EQU 1 ;READ CHAR FROM CONSOLE * CONST EQU 11 ;CHECK CONS STAT * FSRCHF EQU 17 ;Find first directory entry FSRCHN EQU 18 ;Find next directory entry ;This is the section to modify for different printers or settings ;All label changes may be made at the beginning section of this ;ASM file, but line spacing and paper length need to be set here. LABELMAX EQU LINEMAX*LINES TEMPBUFF DS 12 RESPRINT DB FORMFEED,ESCAPE,SPACING,12 DB ESCAPE,FORLEN,66 ;EPSON CODES DB ESCAPE,UNIDIR,0,'$' ;TO RESTORE PRINTER TO NORMACALL TYPEIT lda filcount dcr a sta filcount jz exit1 LDA PRCOUNT DCR A STA PRCOUNT CPI 0 JNZ NOTEND MVI A,linemax STA PRCOUNT call crlf jmp newline notend lxi h,fence call wrcon newline LDA LabCount dcr a STA LabCount JNZ ENTRY MVI a,labelmax STA LABCOUNT CALL eject JMP ENTRY CRLF MVI E,cr ;PRINT MVI C,wrchr ;C/R CALL BDOS MVI E,lf ;LF MVI C,wrchr JMP BDOS TEMP DS 1 ;SAVE DIR ENTRY ;ABORT - READ CHAR ENTERED ABORT MVI C,RDCHR CALLB CALL BDOS ;DELETE THE CHAR ;FALL INTO EXIT EXIT1 MVI E,00 MVI C,32 CALL BDOS LXI H,RESPRINT CALL WRCON LHLD STACK ;GET OLD STACK SPHL ;MOVE TO STACK RET ;..AND RETURN ;COMPARE ROUTINE FOR SORT COMPR PUSH H ;SAVE TABLE ADDR MOV E,M ;LOAD LO INX H MOV D,M ;LOAD HI INX H MOV C,M INX H MOV B,M ;BC, DE NOW POINT TO ENTRIES TO BE COMPARED XCHG CMPLP LDAX B CMP M INX H INX B JZ CMPLP POP H RL TTL DB ESCAPE,FORLEN,0,1 ;SET PAGE LENGTH AT 1". DB ESCAPE,SPACING,5 ;SET LINE SIZE TO 5/72" DB ESCAPE,UNIDIR,1 ;SET UNIDIRECTIONAL PRINT. DB ESCAPE,CONDON1,CONDON2 ;SET CONDENSED PRINT. DB ESCAPE,COLSET ;SET 132 COLUMNS LABCOUNT db 0 SETPRNTR DB ESCAPE,FORLEN,0,1 ;SET PAGE LENGTH AT 1". DB ESCAPE,UNIDIR,1 ;SET UNIDIRECTIONAL PRINT. DB COLSET ;SET 132 COLUMNS DB ESCAPE,CONDON1,CONDON2,'$' ;SET CONDENSED PRINT. NEXTT DW TABLE ;NEXT TABLE ENTRY EXTCOUNT DB 02 COUNT DB 0 ;ENTRY COUNT COUNT1 db 0 SCOUNT DB 0 ;# TO SORT PRCOUNT DB 0 ;COUNTER FOR ITEMS ON LINE FILCOUNT DB 0 FENCE DB ' | $' SWITCH DB 0 ;SWAP SWITCH FOR SORT ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE END 100H $' SWITCH DB 0 ;SWAP SWITCH FOR SORT ORDER DS 128 ;ORDER TABLE TABLE EQU $ ;READ ENTRIES IN HERE ET ;COND CODE TELLS ALL ;SWAP ENTRIES IN THE ORDER TABLE SWAP MVI A,1 STA SWITCH ;SHOW A SWAP WAS MADE MOV C,M INX H PUSH H ;SAVE TABLE ADDR+1 MOV B,M INX H MOV E,M MOV M,C INX H MOV D,M MOV M,B POP H MOV M,D DCX H ;BACK POINTER TO CORRECT LOC'N MOV M,E RET ;TYPE CHAR IN A TYPE PUSH B PUSH D PUSH H MOV E,A MVI C,WRCHR CALL BDOS POP H POP D POP B RET WRCON MVI A,24H CMP M RZ MOV A,M PUSH H CALL TYPE POP H INX H JMP WRCON TYPEIT MOV A,M CALL TYPE INX H DCR B JNZ TYPEIT RET ;******************************************************* ds 30 ;Stack area STACK ds 2 ;Save old stack here FILESW ds 1 ;'F' if writing file EXTVAL DB 2 ;DENSITY SETTINGS ;************************************************** l388 db 00 l389 db 00 l38a db 00,00 l38c db 00,00 l38e db 00,00 l380 db 00 l381 db 00,00 storaddr dw spacstor DATSTOR db ' / / oLIST1 QQQ ޑLIST10 QQQ yLIST2 QQQ&LIST3 QQQB%ULIST4 QQQg!ńLIST5 QQQLIST6 QQQ.ULIST7 QQQ4/LIST8 QQQ2LIST9 QQQvNOTABENETQTZREADME 1QT&cvSINE DQT:" vLIST1.L  !"#$%&'()*+,-./0123456789:;<=>?@ABCDTڡ38%`lC9L!f&Ӱѩ7Q%LaW94jT04 霰e1qDAA',rdҦ.!uqy?l8QPD 'L\z/Ig$& i4lp M6Dl(LÊFDT0_LÊF{LaW/L'D IsP!,plSႂ̴k+Ӱы"6x0 +4jdz`kxkxí cC|(L:'Y%D`2=34jIjB4j#&ӰIsP㭡[TGl!vɤqUBDGdzfS__>IMQ_ tdV|5c2=0sʵt5trRR#x!*ǔ֠ևow?J[Vj$%A+5HtL) n ZvTLIST2.[  !"#$%&'()*+,-./0123456789:;<o=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ]&+ŀ E`RN%dvѫO1 LpB1:s!WdXz4dFYר*C ~D VAVsDXrr!A]CX 6nrupeYpQ?UW!kXcf%:e ˠZÌp4`U%Z*@+]AY顯`&A+5$S':PPBAZث M $Xp+AK7IA h~D(럪pT|RG MW Tޭ j`&A+5lTJ= =e zAzJ xC~D*F$d ~Dx?Un$I򂩖z laf ;r`ZvTOǴlaQ]7[؁zT^,XpFN0tXʈ $Xp+{FAp+{~Qq5~J= ~  ~j3F4hYj@k4 5j jPk4wPQoCÈث>jj*,b*/? nܢ6 lT?G$f giV6K0l`"9"K8 &2#BTpLdT?G` ΂kǽ|#agHr"}R#pw }֠^FtL[Vj$Zև7Ww>uv}xR#ы~!R#.DIpkJD;QpkJD ѽ֠QpkJD/;ʻ֠rRR#x!*ǔ֠ևow?J[Vj$%A+5HtL) n Z]x2>oL^b8ZF4a<ۡ{>o JI ] 5\(\ ~fᯣ4E(.P*1$dj5Lʓu.2o0YgY2so>jQ{Nd$# &YsC"KW :Yg7h˘EH\ŷWjl'q0Z!%SaRaJh,&o.DLA4sSjB]DT\ (M1?DsC"KVä%]We8Ks!Y2&uBvNrڏbÒY2ѫbjA*%FP R] ,jmV"#$#ȣFKK] ,0LZ{&aR/6a sC+!Ug`= +x`'I=F+1`!ɄuzȔ=ƏX1@4Xc]{&Éab='B=&lA`!:& =&ECd`H\1>={`H` z<$WG0\]l'1aJx(B?qߜco{6TM5jȝD)%A+5|Y?K) :rS\nMq).7妸rS\nMq).7妸rM:HN{֠rޥOMq).7妸rS\nMq).7妸"vhLIST10.:  !"#$%&o'()*+,-./0123456789kaqA]΄lfwjd.jpY&t *XDmPd8&jw*&I3^eFdZLT*LLÊFDT0^;(g3"]I__a? 'Y-V|5@_5ӰѩgGpT0^;#8MU~`8jALhvbCIV "_ WaW#6xL&&}?jGMM%|El(LZ\B < &~fzfZWaWS&"6x^;ugm"'ܢ4j#&ӰALLÊFDT0_NRRzhj "p?&}}DmPd8&jw*&}}p?ld bX}e1.?0GVn7,.u I3& Ohj A]P0t6NJhP0xLÊFD֞p%hcA4Xcll5:[b= LAvǠgoeJf)cL$z2WWXaL+AC NŰ)X'lAb=D2`!1۫#0$FCSCdpU G zz$Ѓ'om9zBC 3LzyJOyYAurY/O)IJh/-$w#S^zƠ:9ԬT'gO C,ϩÐ+1 pB+AUkos S^X, ')/+m1;hcP&n^? S^XޣbP ?e{6UmarY/aA kBىE6 |09ԬbTY2S^Vh g1;hcP&;09Ԭ9O )/+[1jm;09Ԭ9O )/+[1jm_wajK|% [1(wajKŷ3۷oOyY-f'm bPaj˅*o@A1lJU&N^S^z\XAurY/uÅ*Ibؔ{ m wX8>Bx~B :9ԬO ۝Ķ=&lٿ8`6fӧƠbxC~b(aQ}s>x03h*f[=у'=&EXMlhU E4d<?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^c[f N^^?Q*`)Er'vؼM)EXٴ3^~ߔ֪}^UM;g8|H-cv~rEq 8oa&zQgC(j:TuCr*ՇXN ՇQ*3;9E_~W*:G_x$w[oM50 3;.{\ J.d]VFT\e<#÷0à`vDc5H Ⱥ[azN@ASqM3f{TCS`oz/c;՗Xj^=cô z,] } ]v@T_bIeAWq˟X[c݂˟,x>.w@T_bq> /;BOlw z,ۻ===} zg_/lgAeǂ z,тgbгa@m x5^ŋ_oAX!U`oH2T̶z45 f޿8-V[1i~q|PxVhc4ypE;a.rG\;8hM[)_*-3͗Wd,fd -1;4!TCbL;*k/X8+x'i`ﰉH1PLщhi`jp UM=x'-| R)kMX5nu{ Ø\`ES4e1&WYN Zr=6YSl|}Bs:  l^1xe+\bL")X{-zkH{M1ES2: h0&ؼfHn"bLєC= Up轃zΔK|whPO)K1hʢ21: 8Ĩ5Fx' lbLW_&pB'c M O1ES)gt2к=)g)_*k+t28f~Qsc,-t2&0%};Nh;p.R)OєP%܀.́mSd,0Zz( ?GنŘb6HCEr~՗^}B'c ?G&O?1́mׇ$\{WXw+m-0jԀ=1́mׇp՗^}B'cznx'm`g°Ø\` c f޽tՍBKL.LNC{ט,@19 PܘWw{ &# S29 ]cŘb6HCEr`_}է+t2ȡ%ށw0&ؼB(3A_*lS.ݫOWd,0A'8މPcUʥ}] I$j1V\p]Ȉ;7o1 eHh#h*xŷbCFĀA`h# I⚌g\ aG1+G1 = hc 'ND)1 M8=\HMޡ&p=ThCdf0t6r `O+g j; M5xoh*1b@bxyvAwAOЃ^AicSlCnGp !vhcPzcNw;9ZAAOAOƠNr5נWXY ]>Au<*as"ncdу'ozTIV1t9dȖ uKhK!G2,h*xa<h@]ƅ|s"˔xژf0jDj1Yg8\HM󍎖VђE|Acѳ0)O0%epUfq FK7LIUsa*CeTI&lgosF_̓CCz m IMƠwX1N+Av8hdђݛm tcN1zp vp v;a m XN.q [u%7K1+\ !}: 1֣AVkaJVXY ]>Au<:F9zl1Z7L =$F_̓h9V ;D)J2bmLBSjb}5Vˠ&\ء߀6 ;lUs7:ZZ2ƪK= 'oZ2ƪK= VIZ.cJ$w[oP%qTsCc@ƿ|o+$k2c@bxyvAwAO`t@6mz#'8Z vGh1wq}]TiclV)fl4>T$޽tNt l^qP)fl4>T$]~uٻWX`؃NSL.4F8@@0&1́mׇdUsg^}B'cWz0;:3)؀bL1s`" ռt"ca:* sp%&'c ɄNd,p UM=A{Ɏ8aŘb6HCE2)= T=X&ށw0&ؼ P)6>T$eEX12ԤbLQ&\`)Z(%%tQ5Vt)oL9`f%6ژVY]ҐcEVLĖf*kQƔQ P"EٛrFkfhPOXѥ8)@LQy?bLQzp8| L/`L %_+cEr>ZPGxEQ&EsRʸkt)MQz, iEdv/3>ǧ_iEΔtgoi21_㙞JVt)L_Ng|ƏO<ӊ.E)ˉ6&\h27gzZѥ("G_E6&Xѥ("3~929 BKLPՔ9ӊ.E9(JlLNEdv/'S&Bc# ,9ӊ.E9(Jܘ2Vt)L_Na߬ L0=˄rh;`͙Vt)Hk^(q]"2;SvњZ[o~y#LO%&RyHH(Jč)DƊ.E;,sESW.29B+}]"oSKCzeEdv/# 2,9׼@Q"cE"Eh<*SBA60F)@eJܰ!dz(羮`=&P{#f< nyHŘX\`"ռ,PkE͔)JliF%nL%R#$%&'()*+,-./0123456789o:;<=>?@ABCDEFGHIJKLMNOPQRSTUVC$F{<ƀ p81Bm:`v._vg.TX3 [Bge Ux(PaZfo`s>l_m-G uJDY mkZo{46O%/TP[|jz[AN݇P 1ѥ˅xwv㺳.!uabE+./2 Xqٙ+"aE v밢&XQ8$cP6ZvbX[mwӻĀjbd*hn6akλ|7CyOUufT(OX(q`(mjVRٙr4w ߜiE'G_EͰKQmc" 44XCx؉wr`+SD+` N37<Q)XnJLJ((q`(mjJLQ~Ls+JkMQPC=aŚ<(.űH LU;9Fw1s(#BK&#UPћQHf2<2\ʌ Lnw|;WĤ" .x{@U>v6gCsN;cZSD!:ސ"vr>؃»p[ZSDx ,#SES9~x\s(Eǂx ..ŗ}]"2Pϻh|sXzF=7A1(BU&X-\\}"sElSPb3(СKQD~>`pf(q@]"2c%QC=aEE뱠%} |{/}"r@Q%Mm@P"DCzŠ.E9S>`9Jdڀ%:Vt)D|,P(9J<}lo!$NMGCDvKo!$NMGХ khQХWaN(q5ĐĉYؼ鈟OWo?}F*Ȗzԋ]P\C'fb##PAuO)wP{۠^NpkWC I͛ o햔TC I͛`d*$"[RS 1$qb.6o: o햔TC I͛XicH,\ltBMc ljL6xsJ=rt7cFv9ktF _h]dOx}݌1z ;n3Q`b3V$c`kޝݠ„'71 cM$؟`k10#^63AP!ݚ;1pom Bi0c{5:OX& Ka֨$1.yŊ:+VV\&+.;`ų`Eq"f$XQh{c`͸F ς 3Ԙ mr"ze8- ^gW#t"cfc`nQ]yW#~Hݭ豢c`nQI_j?{V8c`65B?"fnQ9-b=&}9n6 1fnQ9-b=&}9n6Ŋg11YM=NeH^#54cM PqR1 5;\#Wgx1a?E zRO%oBc[P;QY1̭7*sb!! l މ9'hn6?t7c[oTiWj?{$V53FvN r&~Hݭjw1̭7*+ɓ.j?{V5$Դ0ce ̦Ƅ9~Ќ9~cƋr]u3SM3ZoTPOXѥ(6E;,sE7|y} (=E&kX(29E6&(UbEȄ LJRQ T[rNŘMq,RD_s{Nh)*g(EcR˸70&WY1ZKq,RD\fA;a{z׆ Qwʄ= vJ ) Tw0jCC5"1E ܀+ާ({uwv+6S&W ]"5,PLFS*kKQZS\`BMQʄ)E(h@16CUwiOxLp4;ʤgc; 9cj=ᆜGKA3ڰ\`SD1(5,PLFS*kKQ5&t)z, iEfgr:3~|ՙVt)ΔtgڌM'M`3=R)WgzZѥ(2;Sk0&ؼf<_4gz* cryEL_Ngk|C_4gz*ݰKQdv/3ӟ[Sk뗗?3=(tEL_Nʌ91T57gzZѥ(r5/Phcr]"3~9U!3L 24woKQk^(q`XI6Eqĵn.ŷ)}1E7J(oSG\?uCr*ՇX1WC MG#3dK47NU4Nd͛d:w K[Xb0*l|c#P1j@s![y'jb !XM KT`c yj mr 6GݹTC /bH,\ltT1$qb.6o:bO|165B?gFv91zRO5 -&h=:ۛ1zROoc`nQ  .}V(5Mn`^gt߿A3[oTi `~Hݭ蕎Cc cP.Ԑ-A]c4$lz_ %خ1jĀjMW:10SM3ZoTiůϟ?P:1j$G B1 F#`ri. #Ej/xۨiգ\!eQF#EUgqY {ݽ8"l\51 )d{&#pCctu^!5&ځ,b+xI']]iG0?^ )>>?a 4?>?!Mw}¢pѡWC iXɻ_aѡWC ft@ M G`h9x2 GXV'\!iOX&Z-_&[n<Rt{dd+¢CĂl4nt 7Ы!Et+thѡr[,F++d[Rn9Xt Օvd 7DMTg+@՞1ҎLWCLh“8O]]iGWDMv`(Ǫ ^x(4FWWڑ)DMl2 CcB2 518j0{e;G BtHAw3=I:Ꮟ?1c_0T1![%1*(&Ӆ %4FM&Awb G֝S 8qImfAN mc@5sZ&(V|g Ō14F2AYhBi1cMJ9"fSc*~FJ=~gTމ9'\~HݭJyٓd~W?aab@Gt@FL  475wb&l]†H*eMۙ!65&# a|ctƋM&7*;~~X0Bމ1I ?1c_0T1BI@G!A,-sB+ْGrbRm(ŀjMJ6݌10SM3ZoTiůKg~Jk頻Tyٓdc4F2A"qXL8c`Sc=Mz{s7E ̦Thz}vkD ߮G:nfc`$넫aab@<RuGG)ANK!whiln$H=ƀjM W:=Mzzx1a?#fnQoVH=[XuӞpW#tSt3=I:OÌ1~Pŀ :oD1Z! F.Mhn6ak!XM0 [-ŀ :=Zo{P 11a?FvQWE۶jt7c=I:'f1a.NWOtutx:]]<.NWOtutx:]]<.NWOÿP$m'6k !"1 F#`ri. #Ej/xۨiգ\!eQF#w7-N#˴ao&ZX6heѽDQUWڑI8͏'d+J;2Y$8E6 G~CdE^ )^aA6 GlaO'd2RVXtAB4cA6vcU;d-2W@8͏ GjHQ=a 4?'d:NVXtN3:diWXtՐ":jHZ, 2"Mo5 bAhW# Faܖ낯F^Y٭_<Rp>,F%WdEl4nt=`E-:ܠC XVV"]]iG#Sh#SA6ZYmn(=#Ej ar$01 )d+hql4)aE66jjłpszD+l4m.j4압q7(^qdd+¢`A6ލ~7 i{i{i{i{i{i{i{i{i{Bc?S8C?~ DYaA MF݄=_N=_N=?͛8qw iO8EGm=Z]CB>1WC MG#3dK47NU4Nd͛d:w K[Xb0*lvdLIST6.W  !"#$%&'()*+,-./01234567o89:;<=>?@ABvCLIST5.J  !"#$%&'()*+,o-./0123456789:;<=>?@ABCDEFGHIMU/h6wn8acbe6="r(s0R17x5loqi]?Nޢo8«a#=<_~3بw )ޠexe⊝Ʊuv;{S3o/eTatmmnpnXaѡWCWѡr[,F++d[Rn9Xt Օvd RD&`D;py:|J;2B&jMCY >VV“8OD1ҎL!"5ax(t VVr[d&`7Ga<압s2` &ɥC6ū=nQGB&=O8,ӆ=xX6heՕvd'd+hɻ RD^ )CĂl4Yxv VXtՐ":dI,2Mo52V B^'dIVnuWfև=&=Oū=?هh䊬 Xwߍnpnn¢ ::P-DM-e}L,{:|J;2d&`*޳| EjO]]iGWDMv`(Ǫ ^x(4FWWڑ)DMl2 CcB2 518j0{e;CDEFGHIJKLMNOPQRSTUV] wwݿ3x$LZ$7-xY#G* gFˊ* žŞU@Zj1E]v!vBˬQ</.73TVUߪ\dv:"K8:R  í˙q_nq͎n7U38*v8kMŚhpWb%W3$fpqRF_QۛRunΏI~~x|6oR%Sἀ`ƨ3F`Xie*l:6lTar?"idr?lPߥ.Kk 429V1V%3p \akU2S  U*l:x=~Ը^KpTarbƨ3F`Xi%_ߥbyQ f429Uum٨d@|uE6d@o>Xi?K#]2E WT ] 8F&'*FתdXi?6*m τ!+f K#]2E׀#zY^Zj$WXZTjEˬQ0xq  Um-M',Jp3UK L',0VOFxs -FOQU7[lbt،6ᦊKt+mMXb#lTar?E, ܢCw7Glpnuf)f ^-BڬKpTq&ybr4YnL u_Wd4ͺqT.X9erGgJYPi8:La.7 R|uEa@m%EQZrˬ;*W+K]*l- j3*_0ERUN7hi_xTxZ<|}{y\lp*<-{BEYs2k{y\lp*<-{><.QoRHXi |&H߬!N 1s.X q)s@E o:a%qdRH(D>CKS+.~Q|Bhi iH|ro:aI\%2F[M',=)I\ xI:x |OK$qT$u6Ei{DWANXi؟nq9.a:`u-7 OF {;#lv㌤LQ=wR&Wi%Q!-hGoL.F)qFGK NcaPLѡ%̺<.QmaDt4l8īh(ZEHQoFC*-7t¢uYbp*<-i(ZE)(W\>%jo7 A',ZZ%⑆U*Ch3q:x e]yw̠hKw)x$Hd3C'mL0\r4cDG.P  |&P8%ncZU8#t >k*Ov9d(]Ve*~^VQ B-#ِ]nArCٺKHmf sl1E[|UlTar?H#:wi&us 8aƨ3F`Xie*l'f% 冘8]2Eט.6lTar?6T ].6lf]LNrUULRo>Xi?6*m τ!+f K#]2Ep:RG] ~V|&8FW#u tbٟ7SH#-JpSE\1VOF?-PT w7G,QoTH#-F&'uMo`U`X+m0f3f4R3ZZ,Waf%H߬!N 1bf "[bڬK G0bhTwdocF&'j.akU2SV.6l,Lf]BaP#8Bʫ3V./>|f@m%T(cG+ΞK]mٻu -9eaG+R7y@m%fΰR [̺59 m!p1K]m*JYR8 8WG-ַVbUZZf%/|R|G*6C>Zrˬ;*LъÈ\Q*¤Lhuȑ(x.W0LQ_8"idrχۛ:6bG+*ѵR|̺6lÌu \T'L+Af\ PY/YW~]L̀ڂ/YW~]PPo.U`H#+mDMaQC j\%^o625U:x3 ,025H ӰF&'{=`p ufidrbƨ3F`Xi%ͦ;lHS/VQ cH#h3gh0%F&'{=` ufidrbƨ3F`Xi%4wF=q|JYPi8:3K]mY[YP}GCKNwuGϿ.6l.7j.AEYs]z*rCLXoc̺Z1' 6}c "he@m%àr)ӌ8:K]*l!>YmfBC|-pk<(kA!: 15MV2D93RHXeA # to 1TgB9_vB|ZZld.7")kTER&Wi-8*:xK#8Qo!>[|z#m G8}χۛB%^oVi?n [Qoa:`uf4Olq9l.7[oK7 r_1P&ר`2JG3h(ZE37k Ӏ- w)x$Y \YP Zr_qN 1Bg =͜|f@m%T(vXvLIST7.[  !"#$%&'()*+,-./0o123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZS*+YTx>>pڏ 0];8 }u&Cn) |יyG6YTv9@֌( 0쳳д5Fւ}1Ù8o1~|{ZK#wAv )dMF点a/pmA东\KL 2A6d(d{v~;3JKj;ڨ<8KDzw, =S努Y"j}`|+ ݎ% ipi8HLҌ.2A6d(JhЮ7HDQb1`n-%*|D )dMF,lίwGtFiI͐y\C=Pe/Wuq٩Bf>.P59KD_xb18KD'۳QZR3d6c=Y"JѠQW/(PJwq,NW,/ 1J3fLDQt8U 5I h2jԸ_,> }t8A{TOBrs /15HDQ8Kӓ(-fA{TOuqn%Y"{g 9uD,>0+ ݎY":ٞ_Ғ!.{a˒pC,U#:f\P%aGqv:UDWgd{v~;3JKj1=Y"2,K|ydwܢFqv]P}ԁY"j}`X,t;fgd{v~;3JKj HѠ]JL)agPg(EF]@+ q,NW,/ 1J3fLDQ8KSР]so &Fbsܰߗ[8KS~TOBrs /15HDQ8Kӓ(-f.>GTgY":ٞ_x\%aGqvTMQOxb18KD+pz3\&elɨQ%"Р]so &Fbsܰߗ[8KDWhr\{%I h2jgd{v~;3JKjVr {xxajRghnQ*~d&g ݎY"Zh+͘2)¿U@g9pgb^A&Dto:,#;gQM~P헙iXqwLv{$zIi&//$z9!sRNg׻#JhvC4}&ҮioSuY>AԘ:fН7~ 7~ `;i?2f 3(a3*ՈV/!| tt7 0cFBUZjp i[QQQ?&&gs\{6 O(4U%Ą6 ^K2pH&&gtQh bBYHĜRg#)WTM渜L7~||BBoD>~1Ə,lQ59{;?PF%O(4UML ]^gq~R59r3 =>T!w8`8C"Z߷ #QmPi? M:oڏpZM渜LGBSJ4 Ab)BkQ)(aEEMB6(4UVr^s6 JxQQRTM*-T)aӫ Pr^s6 JxQQDB6XPh1A 0X.@TM渜LMV80*HDBUrBS cLT'_ e/ ًG2qRTt8&gtBSl.*-DTM*-_MFl.*-3UJ U#:f*!*`e/J0c&jrYtu*8gFk XPDlb^=PmPe8HLҌlLM4Z]{Ci Wp ^TK_ǿl WwyZ3/jr6 ^K0#*@, ՀTTMѐ٨A fDS~Q59KDCN݀dMF,}LM45j/s Y" b}ڏ2A6d(zwDg i[QQC"FըfgZjGF,i{5GڏRcgyGpۨ`NQƽt8=ٞ_Ғ!-u+*j(PoC,N(ѭD47(NH,>0W,3Db|! . W1eR&&JhЮ7HDQb1`n-%J ^$elɨQ%(-po0CMƺ8KDs~TA Qi&gW,3Db|! . W1eR&&Y"R 5I h2jԸ_,> }DT)a3*+xAR&&Y":ٞ_ҒA Qi|*%lF, =S^JRWY"j}`<<nnj,lίwGtFiIЫQI*~C,hШ(|E;oBոw+pz3\&elɨQéJhЮ7HDQb1`n-iF%]q/Q5HDQ8Kӓ(-20ЫQɣzz8KDzw, =S>njT%wbQ%(-aӫQI7zY"JѠQW/(PJwq,NW,/ 1J3fLDQ8KSР]so &Fbsܰߗ[8K^Jӻ> My5 )dMF,NOg׻#:fc`WGuqn%Y"{g 7ًjrZBcFqV,/ 1J3fLDQ8KD'۳QZR3d/>a/Kpn􀙳t &FqTM@Y"X3"*Y" : M@+UD4ŨT?TMѐZ̈ |j"ghP¦WTQ5D4(a3*=`F4U&ghը$~̈ @, }ܰը$ M;UD4hd/~hUD4h3=A, ]odh@?%p`0#*_%!3"*~>Y"]ǦW0M3UD(N0<~dD& C8g̹(GF4ͻwE#s6 جY {~&OpB 3t;f̠8b(~P)s?~qkQ}`goTkQ翿RbǺQv UiJNaE4_Ȁh08^gN{Xv΢%ݎWmqϸ ASJ{gRD,Jh +^int 3QaY۷'5DQZR3܅=̠tFqvE?^͍7aRfXzeitҌ p1((E5d˾Ț:0_ 6J֐5ۍ FugĔE59;Kb b^a#fF+߾aXF7_޾=uq3JKj0̠tFq묒S4 J1JP%Zh+͘2)dMF,Q ~zA_?QXJh AL;v 2A6d̰?FaGq(lk4׸wv0O@TMQX,t;fgd{v~;3JKjyZ,a/KF5DT,qP%aGqvFk TMQX,t;fgd{v~;3JKj6 ^KҸ 7zAQY:LKȨDA^P:  UY:X4_HKAbfp &Fq*BvAR&&5s~_n,kq; 2A6d05D|j^ƽt8Ғ!{Io9#v9C,N _޾=Q%[g(Ԡ]{<`E%FqNg׻#:f^|T7z]TZB]%"TJK?_Ըwggp%5 #{}7?FqQZR3ed/JKH=P.*-.3JKj.*-3R47zAw@,NY"uR4h JwQi (X,T{g?9џ?8KZSӮaKK ًTO.f^zz.~>t8M:5p'i]f/Q=2{8uVY:lίwGtFiIp+..3fًTO.0CӻQ%[g(} ܠ]{Y"{g /%xb18KD'۳QZR3Έ VًG`C]%(-gq>aݎFq:fqd->aƱFqTBOtQcgȰ,n05S.7BD,>0~nnj,lίwGtFiIQz_r7z(QzAWTƏ(X,T{gpb|! . W1eR&&Y:}LM45j/s Y:vQ= My5 )dMF,NOg׻#:fc`Ə.ѭDt=;8KDs~Tp`jéDx+^Xv(ъE44$^i I h2jgH%4h$elɨQ~\07Q \KT 2A6d(zwDg  T] 6X, = 9;U%ßBcFq0 L`S-Yy}s]^%Xz&a`r8LLikyl=-.0w ] b^ƽDQZR3kΘ^K-l8C,aY5t,qeit(:;Uvf{~=lwo7vf{~=lwo7Y"ò4jgY>0 /Quv &Fq*v,`LIST9.=  !"#$%&'()*+,-./01o23456789:;<{_. _'W"NmcBEa]Al͇KX!{|'.tw&.)ѺO:9.zM٩O+ӳS`5JiϷwOygڼSu0]dlkNF:Иdl11Ǔ RLZ+/(,xXb1И+(,X`1И Ӟoּ3+(,X`1*:'ИdlјdllјL瓟u,Sooјt<{z8&Ӻ ٩x,hLI'(,evꀁtôۻ_Δ V$ ٩SEdgw4+S @cꓱÄ́:И4v ORa{_10Qx@4.)]*b:,X7V dƤ%DJiϷw杩OT$c`ꓱAtɨQS =S -ӕO4&}jNF I_fJ1E`hByW+0Иn|{W'ch L}26GcꓱAEc2TIu=&czW+x,X_-YUxb10杩Oћ  ,S јdlmјL2;UR] DŽӻZc-YUxdX 4 L\;&Z[6z vLIST8.4  !"#$%&'()*+,-./0123oyv%qkOe^ƽ}%}ܓ[{ڸƭ~Z=[5n|5џ<uzۮ>\Wu5cj~kޫw-%boZn-}]kyZzZ-IhGm?\#rgo7F-$}3qj%n_[m܂Lj>qY%Xں}=\Zj<}6׿ŭrk|j%#ۺ<{]V_~sz?@ 2)V. U+wJ kF[̅PԊ0xu=i [h.gJ A(AOY F@ƘiT&Δ`2xc1 pʝhV04X5u!tc_(6 aH8X`[j|b. $>{R U# M ؠhZ < XkC5q& 6$i"8 .PTR8ޱj4r!hIش݀ \Mk߱ EhFP9ئ aERs ,Nq vA7\$ Ŭ(cZ4[%H  ]Z vr9Ka=a?L4΅`[H@qc. xH(VgJAqc. xHiTtJWޛtrZh6Ԏx7 aѼ!\igkU@l.`^:P`$C,sh)|Jpg}НRcsᬍM㽻)sV`)z@ו4C'|2Fq+u]so5[ë/1igǻ'[VM#(B|=uYi|SxOѴJwIE]N|NrFziGâ7E5ly %,$b]JP$YLc7UM-r)%Ak"uNcgb?1ǯE/V IC6)MV +6)gFWg9zu+REy/+%6 p%Gt]v)x5\)r."W$WW]aA8U+$\WM\1+*q,~+!ɴʕ 91-\ c=Ö;:\EZ6m΢WBKX\[ p%, 7p XE=:[)еp_WI d졗B R+9EퟠNV 58p_Wl-ҶIrNl0ZX=IcQMO8Hh'7B I~}^1GSJ..o i_B[lwxS%! M \ kR^JAG+.!2iyWr , Q Jm΢Vp%cϥ+AR`BŮ^~Gi,0oݚ"J}C , '91tְh[ sJ\'".@ЕcS9::x+,zکA0oJh%EEOslH}?"?1ߏ&J]YA?԰i`ݛ ]9㐧XM+Wms]M/'R,sp%,NMi,'ng MܘrJFVO Wt0qjxNm ¦nX+Qȣ?@A+-]5ZJADBMXԭK19UR\ 7t+%q/ku.WTV[QCMK<C\ ؤ6 kq:1:x+NԨaWS2%JX\ E)NsG3$I!l00%#V?t4ctu6WB39Qæo7Y"ò4jgY>0 /Quv &Fq*v?SINE.DAT o nPOC K K'pCp/\+}go7l ٙt Ƚ# U-nB=9rvP_X tä@3 S'rn(@ݕnh ,tC .!/] )ȜmsA); int block; /* index into out array */ block = 0; if (argc<2) /* prompt user format */ while (1) { putchar('}'); if (!*gets(line)) break; storeline(block++, line); } else { /* scan command line in low memory */ b = p = 0x80; for (done=0; !done; p = b) { /* skip leading whitespace */ while (isspace(*++b)) p = b; while (*b && *b!=';') b++; done = !*b; *b = 0; storeline(block++, p+1); } } setfcb(ffcb,SUBNAME); if (255==bdosBCDEFGإ^tE~c²_E/x[=U͗oJeQ^ZM?o|3z)1sxw[Ex9w^~ 9+ݧݧ_n*\/zkނs)9+'1Ǜ*ŘB`+.=6 nWnX^sz-R>&X v Y E̡$zUM+&.~+JM$1tnMK!̱[BL+qYa[C7p$S$hv3V' Y2ՂU?ם lcF%,.aqEe/$|Ŧu+-ysp% ɴ]q!7j7g{B+ŇJzm-ĽR|UK,.^WsWX95뒰 вR;|oac!H,vŅՓĩAw0qjRA!Kaq!L X4/^A(ssu!gcQǦk2-}'%a A\iWݧ_ +A7<ǁg\~L|k׺jc9^39'tWI4ɷ?1 I~wwa $7 to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::DIR should just had been run. Notice that DIR does not show up on a command line. This is because CP/M just won't show the first command of a "chained" command line such as that created by SHOW1.Ver. 2.0This WAIT.COM was created by MKWAIT char *caller_return; /* iff the RST was one l2 put in at the start * of a function, this is the return address * that the called function will return to */ } ; /* The breaktable "breaktab" records all breakpoints * The table is sorted by bfnt (address of function table entry) and bsn * (statement number). Both sorts are ascending. */ struct breakentry { struct fntentry *bfnt; unsigned bsn; unsigned bcount; /* each time through a breakpoint, decrement * this count; only stop when count == 0 */ int bpad; }; #define MAXBREAKS 40 int nbreaks; struct breakentry breaktab[MAXBREAKS]; struct savearea *cursave; /* points to current save area */ struct fntentry *curfnt; /* fntab entry of current function */ int *curargs; /* address of first arg to most recently invoked fn */ char curbreak; /* curfnt->fntbreakindex; 0xff means no breaks in cur * function, else index of first break in this fn */ unsigned cursn; /* current statement number */ unsigned calp; /* -> first local st entry */ /* fstentry is like stentry, but in the order it appears in the CDB file */ struct fstentry { /* while processing the in-memory CDB file, * build replaces the name field in the * entry with other information IFF the entry * is a structure definition */ char fstn1; /* if struct def && struct is in cdb2 symbol * table, byte is 0xff */ struct stentry *fstp; /* if fstn1 == 0xff, fstp points to cdb2 symbol * table entry for the struct def */ char fstname[5]; /* pad */ char fstb1, fstb2; /* see stentry ..... */ int fstadrs; int fstsize; unsigned fstdimsz; }; int fd; /* stuff for build */ char *inbufp; /* #define TYPE(s) (((s).stb1&0x70)>>4) #define STELT(s) (((s).stb1&0x08)>>3) /* is it a structure element ? */ #define FORML(s) (((s).stb1&0x04)>>2) /* is it a formal parameter ? */ #define WHAT(s) (((s).stb1&0x03)) #define LIND(s) (((s).stb2&0xc0)>>6) /* levels of indirection */ #define CLEV(s) (((1@n 5: $8 ^READ NOTE:q   KÑ Push to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::This file was loaded by SUBMIT and SUB1.SUB. Will WAIT2 allow you to teminate the rest of the commands of the SUBMIT program and the rest of the commands of the SHOW1 program? Push to find out or push to continue.Ver. 2.0This WAIT.COM was created by MKWAIT1@n 5: $8 ^READ NOTE:q   KÑ Push to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::This "Wait File" could have been set up to tell you to change a disk. As it is only a demonstration then it will only show you just how long a message you can have. It can be up to three 80 character lines plus 15 characters on the fourth line. Ver. 2.0This WAIT.COM was created by MKWAIT ng, * etc. */ struct sttype { char tptfnf; /* ptr to fnunction flag */ char ttype; /* same type codes as stentry */ char tsptr; /* same meaning as stentry for next items */ char tlind; char tforml; unsigned tadrs; union { unsigned u; struct stentry *p; } tsize; unsigned tdimsz; unsigned tmul; /* "multiplicity"--how many occurrences of * the item in question are in this array * (if it is an array) */ }; /* types in addition to those listed in cdb.h */ #define VALUE 8 /* the returned value is the actual result, * not the address of the desired result */ #define BAD 255 /* invalid in some way */ /* * #define DEBUG 0 char debug; * */ /* To allow breakpoints at the return point from a function, atbreak changes * the actual return address on the target stack. The trace table "tracetab" * keeps track of where all the active functions really need to return. */ struct traceentry { char *taddr; /* return add1@n 5: $8 ^READ NOTE:q   KÑ Push to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::Above should show two runnings of DIR. The first is the rest of the commands of SUB2.SUB and the second is the rest of the commands of SUB1.SUB. Now both SUBMITfiles are gone.Ver. 2.0This WAIT.COM was created by MKWAIT1@n 5: $8 ^READ NOTE:q   KÑ Push to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::This "Wait File" was loaded by the second SUBMIT program SUB2.SUB. Will pushing terminate the rest of both SUBMIT commands and the rest of the SHOW1 commands? Push to find out or push to continue.Ver. 2.0This WAIT.COM was created by MKWAIT (((s).stb1&0x70)>>4) #define CHAR 0 #define INT 1 #define UNSIGNED 2 #define LONG 3 #define FLOAT 4 #define DOUBLE 5 #define STRUCT 6 #define FUNCTION 7 #define STELT(s) (((s).stb1&0x08)) /* 3 is it a structure element ? */ #define FORML(s) (((s).stb1&0x04)) /* 2 is it a formal parameter ? */ #define WHAT(s) (((s).stb1&0x03)) #define VARIABLE 0 #define FUNCDEF 1 #define STRUCTDEF 2 #define FUNCREF 3 #define LIND(s) (((s).stb2&0xc0)>>6) /* levels of indirection */ #define CLEV(s) (((s).stb2&0x3f)) /* "defining block" -- only before * build has processed the entry */ /* after symbol table is built, CLEV is replaced by : */ #define LOCAL(s) (((s).stb2&0x02)) /* 1 is it local ? */ /* only applies if a structure ref: */ #define SPTR(s) (((s).stb2&0x01)) /* TRUE -> stsize is a pointer to * structure definition * FALSE -> stsize is size, in bytes, * of structure */ in the table is a struct fntentry. * */ struct fntentry { char *fntaddr; /* -> first code byte (the RST n 0x0000) * in the function */ char fntname[9]; /* function name, null terminated */ char fntbreakindex; /* index into the breaktab array; * if any breakpoints are set in this function, * breaktab[fntbreakindex] is the first break- * point; if none, value is NOBREAK */ struct stentry *fntst; /* -> first symbol table entry for local symbols * of this function or NIL if none */ unsigned fntfsize; /* number of bytes in stack frame */ }; #define ORIGIN BASE /* CP/M base page */ #define NIL 0 /* NIL pointer */ /* #define TYPE 0x70 #define STELT 0x08 #define FORML 0x04 #define WHAT 0x03 #define LIND 0xc0 #define CLEV 0x3f */ /* every symbol table entry corresponds to either a variable (be it a local, * a global, a formal parameter, or a structure element) or a structure. * The format is basically that of the CC1 produced symbol!1@n 5: $8 ^READ NOTE:q   KÑ Push to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::You should not see this "Wait File" as the "Check Line Above" has been activatedand it looks for a line that is always there when you run SHOW1.PushVer. 2.0This WAIT.COM was created by MKWAIT_##ͧ ̓_ 6̓_ w#w̓_6#6!a ^#Vr+s0 ̓c| !_ ^#V{_zWr+s6#6!> ̓_##ͧ ̓_ !e9SYMCan't open %s C.CCC%x %s %x %s %x %s %x %s NEVER!9DM!X ~#fo͐T)~#fo##!X ~#fo͐T)~#foͧ ͐Zw#w͐T͐Vo !X ~#fo͐T)~#fon}- !T ^#Vr+so a !O !X ~#fo͐T)~#fo͊!| ͐Z6#6o a !X ~#fo͐T)~#fon}a !X ~#fo͐T)~#fo͐Z##͐Z~#fo))))ͧ !Q ͐Z##͐Z^#Vr+s))))!T ^#Vr+sÅ ͐Z~#fo|? ͐Z!2‘ !U Ô ![ !b 9!͐Z~#fo| !F`iͰ.| `i͐Z##͐Z~#fo))))ͧ ! ͐Z##͐Z^#Vr+s))))!*.Þ ͐Z~#fo|) ! 9!? ͐Z~#fo|? ͐Z6#6͐TF !P90CDBlocalglobalEnter %s symbol files, one per line (null line to end) *CDBError: too many files !9DM͐n&"|! ^#Vr+sn&"| ! ^#Vr+sn}/͐n}/! ^#Vr+s!͐n}͝M͐n&H"|ͣM! ^#Vr+sn}͝!9DM!"3"2! ~#fo##~#fo! 3ͧ !! )v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2hZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! P!9~#A!9"w**w"j!z*"d!"f!Y"H>2^>2a>2`2c>2s2t>2r>2v!"@!"D!@"B!"F !F#x:~#!|2i~# :" 2i +}|~#:G:ix."2i+w# +6#!6#@A2n2?*j**|+`!#"0!#"2!>ڌo&͖=}  w~2ʸͼ56!+W ?_!~7z?ͧ:>͞@w#5.ww#w#w#w*>?@͌>w#͌5> w#@ͧ͵g 2q&0OxG͵j/ʆSx\͞.7:77!a{  ʨ ʨ0:?ŷO !y$ 7o&))T])))!y 2p_ :pvWALLCHRT.ASMT  o !"#$%'&)(+*-,./0123457698;:<=>A?B@CDEFGHJIMLKONPQRSƣ%zg9p On<N|Y]gS5Mt&^A.S)u˟nN6jּ'{ ʵV-lBgɘ"; ki!Sլ>'}kSY?``ȍa=Wwu:ý;"HHY@J_WrצW@)Yq6v9d\q6ptՊ)yp&Fy]7wwQ6_]дnj<)uGk >C-V!1 to continue or to terminate command string. ʠ<< ñ1g.612@*S:G}.%. #::Notice that WAIT5 did not wait. This is because its "Check Line Above" was activated and it looked 2 lines up for "Push". This "Wait File" (WAIT6) was also activated but it looked 2 lines up for "Sorry not here" which of course it did not find.Sorry not here Ver. 2.0This WAIT.COM was created by MKWAIT!Hxq:' 2^gydkdAGCյ6dܭIfx7|~) =ƐS(!/b{$1䥳R)ʌ&Jh;5Y6Y=s砞IRG y.쿄^Ȼ~Q腼 "iO辢=)NߣJؿ9lߍq(%I{RGwuOg{S|g~vٸ E>o%I{RGet||fqϳ_J&t/ T$IqWPR'{t_ þ(%I{RG~a jϳL6;{_J*8}+abؿ2oag~Q"iO辢=)NߣJؿEa_(Hړ=k Wro|_$̾۰_t@IEҞ}%_ wy_ }%I{RGT$IqW*san'+%f:ɸ T$IqMang b\.]д+fxmm"iO6vm43}%_>oþb~vٸE=)NߣJ*8}+ab"UF_(Hړ=: J-3KWJ+C^vv_%I{RG7=7=BK9%I{RGT$IwxAWF\a{V`/CuW`saAwNLaļR 1/8A"Hkz3Y5V<u E-JguUz@d[ h)AuWb˞"HQ{I{]&BVثpW^Xhq\R)J[WIC){%9)Zۭ{22lS^ZRwgC~c易D3+൯ WARSHIPSBQSwWARSHIPSDQCx v'WARSHIPS.BASh  !"#$%&'()*+,-./0123456789:o;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefgz{rb,?Q}'z}wjW滗[n>o^z?rawO?<-(^>}{\k|{y Z~yn^nUDPOT%XTEG}Y QO<^^I^^7/^T:)IAQӇ[t{yXO}$ ՛~v{tOEY#!^㇛?\><}Y *|n//_>|_|OߞKSDۋ "Uvx{}yR_>˟^eul RW'{t_ WK<EaE_(Hړ=?"iO/}QJ*8}ra_;0 WX7:, @IEҞ}%+#מW}/ @IEҞ}E%I{RG1¾(PR'{tVq_}E=)NߣJ ]izfy._|'rmJ*8}+(Hړ=a_E=)NߣhoiKV yx @IEҞ}%l;Jx<W¾(PR'{t_Q@IEҞ}%_ / T$IqمUF6¾(PR'{t_ J9¾(%I{RGT$IPGkR)[^JP/?gAKpz=[c9UGB E=kqc6"Hlre.%l>ǙxNksR,۵ ,j9t3(=/- a_σ,(3:$9)JYh3{Vܮ^ϫ5Ae{tZ]p,cIK<`y6L^VrMa63LQVךu>nNEfIwgT=}o >=EYRZ V,E)]ʲ]\Z[v)ݝzYItCW;)ZGOKQI p{](m_%5C%P,'U!Sn4av|$yfO~RKK;}5Î9)Jf@8,z5)2+J_?<~|r*P⬆z]}yyz˗\ng ^Q_^w7/zr×{s YY*ӷϗz2EPlz]zrnwiOJz7\^5"^e׿o^/,Cۋ Uvço/e Y*|st{QUi?5*z7\JԻ8+oﯿ{RVo=߼\fS3f8uzz?ꧧۧW%^gy)F?V4FҲv]iֲ,/jяZ)N+V%KC6Q+%Դ^JY^2jяZ)heD6Q+-T~jtU%NUkT5FwZ~emt/uPUմiQJQմ~奓v[UM^+&Kz&iC㛥vROoBQ_xEqӷ׫R,'D,'$S5Iw};o6ÛzxI"g9~֓_ T[y~΋~?5.:_$E,',QC5vs3l槩ofخ}vfvOSΛ͐T@8nr&i`]YN]Էs3lWoZ]O՟c0o6ök~vl,'BS5I7M;!a9]tӴÁ,!ˉu=TRW~:vn.Nc~J}Dz傈zzo__\^g I۹d jӷ[nanꬕSN=̛͐傑wMM2>nan*iiO8yj;vf3d`z&i1c07v5jԦ~~7=̛͠Y.XIi@۱{ajP]3c0o6C Za[OusqZ\`t7Y.YQ_ӳ~^YI< X?tMCTV.m?o+YMCjI~xt>j{Z~خۛ?*"7uݼͦiqdy@WC,j5˩=ͦiCPVYPwI?_JfԏꗺU$V8T]~z7,F?ji?58Rk.vn7Ǫnw1v8hJ^?ZJ~jk$^5bdT6qJWν~WS^+ Y fyF?Z*t㠕WS^+%^A<`dnt5t㠕>4F۽VJY fyU~Uҹ׏V_iO{r7g  T6Q+ i?5 ^5btTۋzӭ~˗,O͘偐wMEΛ&zV]~֯?ݼ|_ӱ,gԫYKDUV~xts3j3M^y31j蛶J}r&ofxs&˙"ꚆjfvOSͰ= ݴq횟7a;vf3d9Sz&i@xܮixiV6tXS\VGrEd9^g9 ^^O><>_׫r$rd̽TYYPtXXvS;veߥS-*n'e ,zy_r7g倸~ߥK햲%vw鰞ӱ:5FXqK˾Kmuƥwj[UӺ,gWi/-ws{qV˹N.չN.[rK-.&Y,瀨Kt{YYC@6R[{Mt7m.}h蛶BMѻC`6iMuKBԹM^OnZt7zOꗄi?5zWQs0nw}7ji?5j˙3.#U#.KKUY!vQ+MѝT;\RqqIR%\ZZr%|!rOo_zR ~9'i|COo^g9^^_w7Wl:Bv7S}N.4.qj]jyߥ6Bnރun/_,knv8ߜu~7Bzx0j7h]sHÁKnVV: J~j4aR4k@wMMk`57Y]CZ-jZZfV6tXS\V,D.& uA^YY<I"/v~/"_yyW^-fy*車4Ffyr}W{=tM:K9<(X]ߍrx UMѻ+ Oo<^g!^^뇧g|_d!rCd뻱*.l=o+ KP(jzVps?_wz|z7?* wMMAwMnOf9]tӴA]oPXCZ-uj:fa@̽HӬf]Ef%\n[xwpiI-6,74Ծnyv\v܏UפCߌc"Y]l"\&YnX*r*e5^1 WyȗMTb^1ˍWyMTR,ws{qV,7"v_QX]%l YM܈XO}$4p˻z}x<|&FVi?5"rFn*Դ}WfIDջv&%6ۤy>eIOoQ^^}_o}J^gB=]tۊ4Jl^UiV,PHKԴPmڶw=f9[(t}nVmpӾK1ق: Jn^~~?=>Wm~ߥlj/o\Vm0NK1ٌtJۛjmS?ڋK1,h]Vi?5 jlfm\} 5FZXwP~jtjr6mt} 5FPVYfvm/.jOۡZ ]j|j yخӰ]vz7Tղ>jPVzjYCZe9զztmws?Ui?5~fnն=ջi8xr6F=]tӴA]TPMEPnr&iWmqܮ,g+QCզ~8i˩䰛W-v=d9[ɺjM?VT71 ]VR[~ߥe} R[a.&:˙Zo^>|z|_޼|Ϗ]>Ӌ^\Ē:_$EC|YPVW:.a5trOo<"^^/nn/ǛgdyDzwc%K5U\v]SYUKP(.iJ\EߴTi<"FMu7Z}yZvXd9cuej%adije9]tӴA=o<"{a5?M};7s3lO۱{7a5?M};o6f3dyDt=]tӴÁJ`9nÛ,HZǗE7_/>\^>㏇Ǘ/ח_,Hknv8MGԏC54 h#kO6RQT,ȨTliiU#[+~xr/?|y,gD,gDֻ+Z}K5U\v]Sٲ{V~[Q\vz]IiJ}f9#jG3-#V#- DKUKYΈknv8uݼM3隆jfvOSͰ= ݴqy]Էf3ly?o6C3h_Q*wMMv횆7YHACzVݾR^tn.?<|_||qWdZn/ujw|M'}|u߷?<>>}{*wMMv=YN}$4pxܮex匂jYPVZjZjOn=iu\QDeWf9]tӴáoy~xm\~j(f9c@mfKYD7sy>Uit7d9cPVV֊,g4ԫ|y?njҴe4rFUc3o狤4?Cq/"P3ZW6WYfԏ^~jnn/Z".ws0nu3n״mU{^]:tpYZ镖8+3r7Y \~mc՞5F}՞8kiVF,gdԫvXMnFTFMS5It,ws0F?=kOiVF,g,Q~]۪̈=]J]{=敎YX^hڳ^D\4+a3:oU^]R,gBԫnzwz]mzwz,g"ԫ?6zw#»ꗊS.|:Vw}7-;n'w"'mǥ&fuP=.F_]i?5 1#j;Vq~~]57wmtChOF"H:_$E\a_uuz=")ey$U6s+B~j4bGSn?WA4F狤~~{qvIhw鰞ӱnNFC(m_DfԟˀZ7_k݌~Iu3Ͽ%MHYI"/v?/~{qh|}y><6ۤy>ey4dM}VoZYC5vs3l槩of؞]~li]a;vf3l槩ofhXTqS5Itdy4bt7YMP: ~ׯWWC"^g9!bFnH~jt=S?TyӺt=S?Tun,'DB]=Ͱ횟a{^wKק?QWN(k_\>>_~qy]Էf3ly?o6Cb@=]tӴÁJnOfӴÁoÛ5 oCZ5 jզzhFnH~j,*ȲL*Eu;i]YU)ˮ2YƊHMwMҩ V}?v;nw~87YNwMҩ jr&Wە,'Dce5UrBdۊ4JQu3"M jJjѻ޽vM:K9RԴmU뻑okפû1 )j_]wCd9!:_$ECeH@YNH6ۤﲜ&}儂kf9ź b#p& "5WL(6rgm4klߥR8tH&O S2׿\YBrf &%`GtS& 08 0[@@`@lAقf 0#R4T+-l ٌLWALLCHRTAQMWARSHIPS$$$_.Ooo߳<"uGBB")ݾz_~Del zYuF9n!G,Du.gpIX2bKjG"CQ˙*\UTRYu'.gpIR2JK+fy$Avpyp^y뻱hW呄YEߴ/oZxI}J˾KmKS^4+\ ]K0#ID*|.)U8VKVuriU,$Qtjw^]AcGzӠW^p(YIbWyA1#I,twѷs3o Տ*VcKK/ܥyBDmCF͐͐~#fo~#fos#r! `i͐`i! s#rzx͐#6ͳ͐ n&|g}o|£`i!ֳ`͐#6ͳ͐~#fo͐ ##~#fos#r͐͐ !9%s is not a structure element !9DM! `i͐! s! n}(S͐!)͐! s#r! `i͐ٴ! n}av͐`io! s#rٴ! n}0³=n?Ӭbu;vo=ܐ\ꚛOs_u͍|^Ɣ]K矍Œ2k nH.VuM)󻖗?cŒ2kϬ\\Ocknd~2Z^n_:c0cZKs ŪiTFw>/ce/ nH?.BjEG8ց  }`SrZ4+=3ktȜ nTƼ !K|Fցg v0S+> Yο3=O1{\pC̵&'gK|:YA=O)=sg=ܐ17s̟Y^Sv;vd=h)Z$Sۗ:hHgnu%z.!չ9:WcnZ?-ο[7Z_Y7$DVs3ךRVP+н^+eK t/;В˒\pCBt':`eȜ̵&W=!pBv𩔭/{Va/Ks 耕rj\kr s'0oP( J:*̘}"cue\pCsrQu̵&#~ZJY_Y7Z_[A@rz -?ݾ:\pCBt':`e17s)e*̘}kue\pCǢt,2LqqY:WW)Y7$ :..D9Tݎ 3fXb]R=A6~}"cO̬OvW{9WV矨YA@rz -?>ku\pC̵&HD;Ƭz C9 #g~Z ڜ@J'Œ'2V nȘ ߓ:6fcaae?juhWn? 3fˬ?ͬvW{9-vWEATHER.BAS; ! #"$%&'()*+o,.-/0123465798:Ϭl+=9\pC{5ul0sH4f5*۱/Y786~*GG {57z{4YܕY7ryӱ+FwsiVa(ۧ[/:Fs yAS9 +TPX 9r0 eEvZ7d=hp8]RչI{ŽOݻ =.yI?z.!չ;>v+(۝NZGP㧝 {Efs(eOf=hNeuHv;v>=+S|JVa(ۧΧ*̘MfݎO\pq:-憂t>iV'e"OU;4 3fhk=hN%{ՠE>uO`+(&z \A1A)|bpO4bgf掲}gu>{ValZ|i\48? S:eV'⟜D0w}gU1%kxF`uZ./aخ{=讘AtW9Y糑F$糯U;}5cff΋f=hN%2L+2qҝq=("*"b sG>&Y30cV4kEF`uZ./9X1X[߹WL}+fz:P푓ݎ5+bOKu^Qa΋#0cVu^Z7ryźDvXhtO{fVa(dyY?ݾu;vi jwK?ݾ%+^N/sdtFeVP+н^fCK6~}#kh=hN@7g?Rါqrp~.̷?M nHlh۱O㭋]?md^5~}|2xqɜc^5~}|2oVP#?>>Valuz.8XˁboDWwÎ5ܗi9v,[Ynh˞Rktxƺ;x j1}Z3VP&)Og۱YA->Rktxƺ;U1:xz.8XˁboDWwÎ3}nZNnοYng}|n߈7JVP^xk jC?ݾoo$ZAmxY7u40c6K:F\pq:-XK=r;o4. t:F_+Gktοc{fn73׬Of: j?ݾofοo 3f3Z7 n4Vryp0OrXοh]u}5+E1f[A-O1kߑ"ktZA-O1k_*̘Zcs\^{c}6#:/X?YnLZDhn3dVPxϬcFcD+E1#kf?>fd? 3fEZ3 n4Vryp!-rX|]?Z}|n:l;.6hɞbktLd j'6~M&Z|*̘:L n4VrypUnDzu>f]u>o{hn{:ld{in{VZd=v켖Y7;snk\pCny:s y.Fw:y {e~W{9絑\p۱z.QEȱGչs3ךN:1snf=v<2hs:]:P4Fz.އH9)YHXDlցaj\prޘzA,Gt+ayy\Lc h#eE}ؔß;?zVpCw}lZG:P4.!nΏ2@`pCLΏD+ F?ݎfO_nΏxd57dź`+(eŒz.!c -gżq0cf~z.!c -gżqAuELßrSoEj3Fn,K/qI h(dz> )?u;vY"n,W翼u(u:Dh9)Avwd(|9Z7$2L+2q*K]Gyy\L&/OZݐ+E2}jtˈyƬY[fdݎg\pC"De)8jfj_JJYd=ܐC!s&5>O*P:ݕ۱Lff23\pC"De)8>Ml׬*Q(ecz.!7B*2Lk|T,A7Jy 3fZ癑\pC"De)8>^3k̾mUB)[癯\pCnUd(< CY*kR:0ցarScm(izô\EwMÞ۱ϒuw WsYfOn}۱D+4}$}v>Z'cvFZ*̘ՒΧi(lGtRါsmᎴr;Χ]ΧYlSDJu>=z.!q=Fց?:*̘}@3YOɬŒ)=@3?:c0cgu> jOnSƘ)VP%}6_s>% jn5S⭠Mz̔mDs>ԲI5~M)} CY*2б =.Vd̵&ݎO 3f۱)3+?ݦ,3S CYzj\krU0Lb{\ q̫u>e*̘M|nΧ, nHr0 e17s);@@ ڜ@+RΧLHmF|4(Ps3ך\90 vB6'#ERΧ 3f۱)Y7*!0"\̵&ݎO*̘M|nΧZ6}'FmtD͜OYA->3SOI$>(P>A]KI?ѵ+eOb 3f۱I̬ CY*2б =.VUu1;>s&WPn'Q 3f۱IԬ2~ZT,N8hQkSMbV2_[7$2б J:đU1dݎO jQm2s>ԲI̔m4v|z.!ᖃKD;r9خu>iz.!vG7Z%|OBGybIà'-YOes ?-*Pz?{Ӂ"N#`^v|D0c6ɺ;4z.!ᖃKD;mOtJ|xlh)= gA)|FValu;v>i_+eG}f 6ϜOc=functs; /* no. of functions in table */ int maxfuncts; /* table size */ #define LINKED 1 /* (flinkedp) function really here */ #define EXTERNAL 2 /* function defined in separate symbol table */ char fdir [512]; /* CRL file function directory */ /* command line parameters etc. */ int nprogs, nlibs; char progfiles [30] [15]; /* program file names */ char libfiles [20] [15]; /* library file names */ int deflibindex; /* index of first default (DEFF*) library */ FLAG symsp, /* write symbols to .sym file? */ appstatsp, /* append stats to .sym file? */ sepstatsp; /* write stats to .lnk file? */ #ifdef MARC FLAG maxmemp, /* punt MARC shell? */ marcp; /* uses CM.CCC */ #endif char mainfunct[10]; FLAG ovlp; /* make overlay? */ char symsfile [15]; /* file to load symbols from (for overlays) */ /* C debugger variables */ FLAG Dflag; FLAG SysStat; /* TRUE if "-s" option given & now active */ int SysNum; /* index into libfiles of "-s", or -1 if none */ FLAGܐ[ȼr9^uf|]-2б JYoValu;v>z.Q`P}1'vOE<>T/۫Ռ?ѵ+6~E:\A)|*̘M|VaFց?:*̘}@3YOɬŒ)=@3?:c0cgu> jOnSƘ)VP%}6_s>% jn5S⭠Mz̔mDs (or) l2 l2 chario -ns */ /**************** Globals ****************/ /* The DEF_DRIVE macro is used to define the drive from which L2 will * load C.CCC, DEFF.CRL, DEFF2.CRL, and DEFF3.CRL (if it exists). The * macro takes as an argument the filename and extension, and "returns" * the name with whatever drive designator is needed. The macro also * encloses the name in quotes; thus, the argument when the macro is * invoked must NOT be within quotes. * That is, to open C.CCC on the proper drive, we use the C code * if (ERROR==fopen(DEF_DRIVE(C.CCC), iobuf)) ..... */ #define DEF_DRIVE(fn) "fn" /* Make this "0/A:fn" for, say, user 0 on A */ #define SUB_FILE "$$$.SUB" /* submit file to delete on error exit... * if yo iWEATHER BQS*pWEATHER DQC+վvWEATHER.BAS; ! #"$%&'()*+o,.-/0123465798:Ϭl+=9\pC{5ul0sH4f5*۱/Y786~*GG {57z{4YܕY7ryӱ+FwsiVa(ۧ[/:Fs yAS9 +TPX 9r0 eEvZ7d=hp8]RչI{ŽOݻ =.yI?z.!չ;>v+(۝NZGP㧝 {Efs(eOf=hNeuHv;v>=+S|JVa(ۧΧ*̘MfݎO\pq:-憂t>iV'e"OU;4 3fhk=hN%{ՠE>uO`+(&z \A1A)|bpO4bgf掲}gu>{ValZ|i\48? S:eV'⟜D0w}gU1%kxF`uZ./aخ{=讘AtW9Y糑F$糯U;}5cff΋f=hN%2L+2qҝq=("*"b sG>&Y30cvYWEATHER.DOC>  #!%"&$o' ()*+.,1/02-_S5r4697<:=38;Q UZ_R^UxǑT6{ܷz;oX2PԷ?0p:O+=Eׯl~U%1sı%^^0ֵ;Ӷ:Hoov޶kar {뢩qD'?<+2^ Lqe  Äsܪ wTǞCV _wNx-m֪KX Z@j~dɞXyPZڬU7fćCp/VMM LBR<WAIT0 COMWAIT1 COMWAIT2 COMWAIT3 COMWAIT4 COMWAIT5 COMWAIT6 COMWALLCHRTAQMWARSHIPSLBRWEATHER BQS*WEATHER $$$$V4kEF`uZ./9X1X[߹WL}+fz:P푓ݎ5+bOKu^Qa΋#0cVu^Z7ryźDvXhtO{fVa(dyYZd=v켖Y7;snk\pCny:s y.Fw:y {e~W{9絑\p۱z.QEȱGչs3ךN:1snf=v<2hs:]:P4Fz.އH9)YHXDlցaj\prޘzA,Gt+ayy\Lc h#eE}ؔß;?zVpCw}lZG:P4.!nΏ2@`pCLΏD+ F?ݎfO_nΏxd57dź`+(eŒz.!c -gżq0cf~z.!c -gżqAuELßrSoEj3Fn,K/qI h(dz> )?u;vY"n,W翼u(u:Dh9)Avwd(|9Z7$2L+2q*K]Gyy\L&/OZݐ+E2}jtˈyƬY[fdݎg\pC"De)8jfj_JJYd=ܐC!s&5>O*P:ݕ۱Lff23\pC"De)8>Ml׬*Q(ecz.!7B*2Lk|T,A7Jy 3fZ癑\pC"De)8>^3k̾m:l;.6hɞbktLd j'6~M&Z|*̘:L n4VrypUnDzu>f]u>o{hn{:ld{in{V}v>Z'cvFZ*̘ՒΧi(lGtRါsmᎴr;Χ]ΧYlSDJu>=z.!q=Fց?:*̘}@3YOɬŒ)=@3?:c0cgu> jOnSƘ)VP%}6_s>% jn5S⭠Mz̔mDs>ԲI5~M)} CY*2б =.Vd̵&ݎO 3f۱)3+?ݦ,3S CYzj\krU0Lb{\ q̫u>e*̘M|nΧ, nHr0 e17s);@@ ڜ@+RΧLHmF|4(Ps3ך\90 vB6'#ERΧ 3f۱)Y7*!0"\̵&ݎO*̘M|nΧZ6}'FmtD͜OYA->3SOI$>(P>A]KI?ѵ+eOb 3f۱I̬ CY*2б =.VUu1;>s&WPn'Q 3f۱IԬ2~ZT,N8hQkSMbV2_[7$2б J:đU1dݎO jQm2s>ԲI̔m4v|z.!ᖃKD;r9خu>iz.!vG7Z%|OBGybIà'-YOes ?-*Pz?{UB)[癯\pCnUd(< CY*kR:0ցarScm(izô\EwMÞ۱ϒuw WsYfOn}۱D+4}=n?Ӭbu;vo=ܐ\ꚛOs_u͍|^Ɣ]K矍Œ2k nH.VuM)󻖗?cŒ2kϬ\\Ocknd~2Z^n_:c0cZKs ŪiTFw>/ce/ nH?.BjEG8ց  }`SrZ4+=3ktȜ nTƼ !K|Fցg v0S+> Yο3=O1{\pC̵&'gK|:YA=O)=sg=ܐ17s̟Y^Sv;vd=h)Z$Sۗ:hHgnu%z.!չ9:WcnZ?-ο[7Z_Y7$DVs3ךRVP+н^+eK t/;В˒\pCBt':`eȜ̵&W=!pBv𩔭/{Va/Ks 耕rj\kr s'0oP( J:*̘}"cue\pCsrQu̵&#~ZJY_Y7Z_[A@rz -?ݾ:\pCBt':`e17s)e*̘}kue\pCǢt,2LqqY:WW)Y7$ :..D9Tݎ 3fXb]R=A6~}"cO̬OvW{9WV矨YA@rz -?>ku\pCӁ"N#`^v|D0c6ɺ;4z.!ᖃKD;mOtJ|xlh)= gA)|FValu;v>i_+eG}f 6ϜOc=ܐ[ȼr9^uf|]-2б JYoValu;v>z.Q`P}1'vOE<>T/۫Ռ?ѵ+6~E:\A)|*̘M|VaFց?:*̘}@3YOɬŒ)=@3?:c0cgu> jOnSƘ)VP%}6_s>% jn5S⭠Mz̔mDsvYWEATHER.DOC>  #!%"&$o' ()*+.,1/02-_S5r4697<:=38;Q UZ_R^UxǑT6{ܷz;oX2PԷ?0p:O+=Eׯl~U%1sı%^^0ֵ;Ӷ:Hoov޶kar {뢩qD'?<+2^ Lqe  Äsܪ wTǞCV _wNx-m֪KX Z@j~dɞXyPZڬU7fćCp/ct funct *fnct; for (i=0; i>Valuz.8XˁboDWwÎ5ܗi9v,[Ynh˞Rktxƺ;x j1}Z3VP&)Og۱YA->Rktxƺ;U1:xz.8XˁboDWwÎ3}nZNnοYng}|n߈7JVP^xk jC?ݾoo$ZAmxY7u40c6K:F\pq:-XK=r;o4. t:F_+Gktοc{fn73׬Of: j?ݾofοo 3f3Z7 n4Vryp0OrXοh]u}5+E1f[A-O1kߑ"ktZA-O1k_*̘Zcs\^{c}6#:/X?YnLZDhn3dVPxϬcFcD+E1#kf?>fd? 3fEZ3 n4Vryp!-rX|]?Z}|n% -07FEB85 ALL COM 8READ ME WHATS-BMAQM!`(WHATS-BMCOM XMDEL AQMEXMDEL COM !9"1:2 >AA_  h22#R2#2::<2::@x2 j:`2*e: z.'+ʚ::æ`4´:x,ʙxɯ2::<2:O: K_4 44C4K4XK ++ ABORTED ++$+~\ O:0ʈ1ʚ5ʤ6ʮ  11ý 3õ12õ2400 bps     :_ :s being done. INFO: A companion program currently named XMDEL deletes all downloaded entries from XMODEM.LOG, keeping the uploaded lines. Since this is a small part of most XMODEM.LOG files, this allows the SYSOP to easily keep the "R" and "P" entries for a long period of time while automatically minimiz- ing the length of XMODEM.LOG. The combination of WHATSN01 and XMDEL for WHATSNEW makes the entire system almost self-maintaining. (XMDM104 asks for a description of the file just uploaded and builds a file called WHATSFOR.TXT. A small program called WHATSFOR.COM then goes on A0: and displays the information. That program plus WHATSNEW make it possible for the user (and poor SYSOP as well!) to learn more about what is on the system than ever before.) It would be nice to call the 3 programs: ALL, NEW and FOR, but would require quite a training effort. (Even XMODEM is a handful to type f_*~D#~ **"*#"#~D~ /h:Q  :::  D/U Filename Size Speed :ʽ  Date Time Uploaded by  Uploaded by Date *O/OO/ [End of listing]$  ++ FILE TOO LONG, NEWEST ENTRIES LIKELY NOT SHOWN ++ ;_ ++ NO NEW FILES ++$XMODEM LOGTOPIC: WHATSN02 (WHATSNEW FOR RCPM USE) FROM : IRV HOFF DATE : 07 FEB 85 NOTE: Modest change added to WHATSN01 to show the first digit on files 100k and over, in the "Size" column. (Did not show on some systems.) WHATSN02 is really two programs in one; change one btye in the .COM file to get either: 103H 00 displays XMODEM.LOG in reverse manner, last first 01 displays only uploads, replacement for WHATSNEW.COM The first option could be called ALL.COM and or file transfers.) - Irv Hoff W6FFC 07 February 1985 v>WHATS-BM.ASM^  !"#$%&'()*+,-./0123456789:;<=>?@AoBCDEFGHIJKLMNOPQRSTUVWXYZ[\]R\I=[w4e^,>B3kǰeWo?O_0R".٤WY|0>by*) # R)({"2x?b~u#1ZˬHa04aQ搦' 㫍|Ce5ǸAMp'x0h³G<,˼X^%=l|P:DWvXh[OP aYHa究GV/ppP aY*)#4?v [#"_SvJ ?O=- MjC#4?v<>ڋ:).~6_/VxXyF{,vZ"Z%!VAaؤ6bsP98XsTI CTڮ^&uWR)_0Ro?O_yʧ[`5VVk셏GQyZJ ??ogNN]bqUput on A15: (with other private .COM files) for the SYSOP's own use (or A0: if you don't mind others using it.) It immediately shows the most recent file transfers first, a feature all SYSOPs that have used the program love. The second option shows only the uploads and replaces the WHATSNEW.COM file on RCPM systems, generated by D-32 and similar programs. It should be A0: drive since it can be called from any drive/user area and reads the all "R" uploads entered in XMODEM.LOG, then shows them in reverse order (newest first). If the wheel byte is set for the SYSOP's use, it includes "P" (private) uploads. This offers full security as well. Read WHATSN02.DOC for additional information. The entire .COM file is only 10 records (1-1/4k) long. NOTE: Prior to XMODEM101, private uploads showed a "R" like all other uploads. They also had a somewhat different format, although would show correctly in the "as is" option "0" on either program where no customization i%%^ #A}(/8gvj{aO%eaԇ2K`7XAYG4ESva<,˼X^%=f) \c/"|g֎au 4;lV~1A' !VSeᘥ0h,లNAJO6 -Z{SZn O!MPP 4_Ia0WX3c5.j`Uퟃb\uOjdkTV#bpJaFFbE83!ME !j̟As ށ*!MOpV >xqEUxc+F뫊5GJ.٤Rl=rh~vp v*gV+`voHm<"Ր') /W]b32/WIy^Gd/g)f夸f,By>pFe^xZ #!Z8`Fۣ+F^84ES!6uXvİImhlLO#*qy&Ha& G :{)+R) NyexcȰ8,%UW.b͠`O?kTV;ap auSv_ e^,NY- q;9+)HqCAbAya+\4)'ŨFMKa^0Rb'qC@d}824AG)7DEla+T>e_>HqC@dȨ[)&ۛG*~z * y*m9)^ #6/k߇IaeMŏZ_DۼQBjvN>?nhGdp &PQiFgS?nR{X4Ab eٔل7ODSS#~͋)+g$Pv;"{VXlp*By$Qv_ jNy;-ZjRbFŏ}%2(7zʧ,EuAŏNdХ1ZP, ݮ z-}|HQ'2 NdPBVsRqC%2Yap4؈ֻ7)^ #Tۣ+8rhXF #=F [NdD #>5[eԍpX&exXyJ{ϬKQN'kʷTN'rFdP&e8Ny𪱃BpWǣ|K"ˋȠʡв(oF #E=5%s:k)(rDNśTI}#23+TV{%%sc=ɺodPSaQHAIzr 2gŠ5GVg48RP=(o'2,HaPB3k( 0e^,As@lY #-_T7uԬ08P2/WIy9HA˗9uc]Ln^ $m^R)h2lKAdPB3CY<,˼X^%= 7s;HA1/sƺHeIBۼ0R) G8;)Ka.K'~"[1yRP0||'|S7b&uY6/k)h>)#2^n)BlU k) ~^I=+.r[lQYP+)^ #|X^Kag) eX&Do#6uXa1hQ',Bre^$"I C-!)Z{SZnQ*mWxXyJoRR cؤ6ոempBHW)TC8^WG|x%¼>Ka0(y90x}W) \, ^84ESva<,˼X^%=|g֎ 1>* =q^HaO?w 4vl7DW!MOR) \N'r,-;RVxXyJ{ޯ0;-cVÙS{Z~^NNCz؁&e̩~Z>Ka0x f Ǡ۔`7ۈ3B Cx_08Fáe )/8`7ۈ3B #y}7)ڤ5kh8GDE݈3WV3Bl*a+`oN CxTxߑ+,byE& 'U Cx3kǰe_#_S6 Qy+)ߤ0Rj2v@>(zïgR) ߱vC6gen\?` OU #!V dӟo6 -80Rlk\I=+.mnk7glUaӟJa0O& Vq{ LAk_\Y͟0Rc}{}{zlRֻd?}/_08تHaO8JAw4+g̢)^Ia.K'~"[_o6 -PS~/^ ʷc([ӆ/5& G_/ߠ,j-u<]?&"x]qTWWWq-2ř{.KY#2 >b+OR)=jTڮʧ,/<^S0|lo˜L $m^R)(yS>>ΓB Z̩"˥.Ke->Ƞ¾"}eoDc7qlfPRP7ӎȠ^+/RMrVLtbFH+)˒D ʷ7Mx'"Q}R)+ㅲj3(T>ezUPU}<~Hq5%s:Z z-CUFh[Ia^Ӳ|l\ܳ+h-CUٜx 2lꄳWRP7_D9Ug;ϿHAw4+&Dc7 n:|$2(b [)c_ 2]M{kò̋URGh~fR)(3e"}FtAu1˥$Ϩ+Ƞf#*¦*JAeQ&>ϓ?+DFwL 'uer\ڸW83|DSXtXExBj㑵F #A ;8*_aN5Tg) O7Gr +P?2zyP?OlRZnq>Ia0خ׸6Nߥ0gtvفâA#éG\x"F~M}db-~F78eW젚#|r:3`5nPJaOQ+A5GXCU?}e!MA34vD& ' >g֎auzfppu *CSWRKa0qh_HQ,  iʧ Ctk7ba:ؘ(y9 S83#v1#3PdySvDDCzcmVmH󗂊7D2/WIy k8AÝ7&q>)wpPYou9; 0Rв|lܳj&Pq7)i?Lhcؤ6HAwdGd0߽C ^5vPhSOzѴL &w];R؋(ՓIDwS^;)n9>OHadwMtN~Od0iCgnQIF "Tèp NG,c).>L 'Փ/ JհٱB#Y[)}ᚒL Y0!2WV^Ia5%yF],gDм⨠¦*baXKAYOTO2f9Ha04ʦ*`?RTV,b0RPgTN'3"{Vm>L D *,uerܳj 9,ޤn:?8{myan|¦*V }e#2WVaaaq;baq`)hYP6n Jհqd0MaXKA$zRAfxj,l|fP0AtҬx*l a/iQZ #en:N hV#Tpl鰊')iE .f9TϬOh;,l:"vR./RPg4/"{ʢNxk>}G#"}FtAgIA$i?HA˗9m怒.KYS F/sڎ=A >"`aS* ݭeIBu1wR).?\eNq=AͱEۄKAw),Hqn:["QA5 ۵tQ]r)nAW)˒b j-M>h]n:{)_k)h2^ $;)˒b鸞.KY,I.fN [Ni8Ja0R)/sڎ{쥠.KY/sڎ^ $;)h2.KYS>g;)?״|vc/uYP]|va/-}Fv˜~,I.fN Zi;oRrJ>Ha~Yi2KA]$T|'-__R)Y}.KY/sڎ^ $;)lwM˗9mz/uYP]F|v{M˗9m=RP% ,IA˗9my/uYP]|voRP% ,IA˗9mǽKA]$T|'-_KA]$T|'-_KAw),Ia~Ja0RL +v.E7HQ<'4-ܳŠ GFh[IA˗9u㴟&DSŠ G,IheIBdO GOqjG)(R׏㸖HAIQEOdp V!E3kxٜ֏")־!(18,_3)h2nMݓANYͰ} )As,IhF J.z"{VP j1hOcsXIAlNRkThfTV# )hYP1fReNXI^#a?R?eIBۼ0RPrHr'YM D ꋉF #<>26Gm#rpJx8TXaʧ#k+w+g5,!MY#(Bh[!T5T#k U AY}%bL5=L Ѥ#b‘VsR)4^Ӳ|l\ܳ¢ Z $ߦA9͠4=ЁMaXG,l:p/sڎ=AֶذEkQÊbKa^S7_bL Oam‚M:"1ZP 8ͻMR]Gu1ˉ G0*2#KAwt.Ha Nٕ#;RFSd)L sIAwT`^n#WRPgԕrFdp a,l:"v xC8.+D鰊r;baq`)eIBu1wDSBSp`)˒b J'uY6ɉ G0ahbB]XMXS)_tQ]r"QA56(ftI $;"Q)MX0BX bdm Hq隺霾I .f9T+Fۣ+\QIAwYNd0¦*_G,lT>,uYP]TFSp`)˒b p`'-4+&DǁqUNVH}dÊ?KaY~Mӛ@"obж eTX4AbsXIA]$TLC/M) Y͠p5BjvxH1+&462.jxE dJd0pb#+hUj)n9>O)̎8BV5q>)\]]Ia0R,]>Ё硪X#f礠eBٸ%2g0MaXoRP% 7KArJ"{Vq3(bж9,ޤHa~Ja0R,O(IF],gDj;XtXEeIBٶ'D!*(^!C{E JCԍkò̋UR"}FtAu1˓Փ/ VxߑȿHAeQ&}Ьx`j}TP+)hYP6. &*>L }<&S)arHȠgf4 m5;'ń zVj+v.Y sS # fPX4Ab eF T>ebWT^;51WP kwRhkWabj;,BHQLCMӛ@ȠVV3TX4AbjD{!%$'2 YA5PU>*N zRPrHr^ ʳr)>$9%Y=ý4-4/ YA5EtX(8śTOʉ je5C5EtX(RPrHrNz"{VP $9M'=Afbжb"z)HaP7A5GF +^Y}+ 'X4Ab->4=Ё`MaXccWFG eTX4Ab-uYoӂȠBYtw4eBٸ$2g0MaX#RP7SHdpB@#bnfTK"yhՈ#+Dh Z a}ѻ[;>F #D*W,R-;cPFT>e)״|S7vIYRP0||'eIBۼ.Kʶe?L I^Ί["yhܛߠвV dӟZ Jd&u9IA]$4OD ʷO٤6|ڏ]?&c׏㸖+DFc)#28B:39KA$M RNFF#CY^HAIQՓvD~xsH樰')hYP7fDx:h$()fTlf,,I.f`:(+j)^ #AvZ9zI  GhNq;<(ؘ8RY #E-5MoM}\ JA˗9ucWI6!c'l4;ǭeIBۼ(>(ۖ`^!Z q;B5Q8|S7yWΈ fX4xCe5j%uY6/k)(Ƞ񙵂6XRP7Ӿۿ~Y ^$/Re۲줠n:`I)mOvD юP G,lT>,u9_"W&/Re۲줠n:}>(ۖd'u9ʶe?IAtNt7l[[)ٶ'kS 04S4-KArJ)hZN@dХ4޻,Im~J 7)˒`^nj8b}TgV\8oqmOHm~r{MrJ[)hZN)RP_L0WO?0R) a0l,Tp*h[A5goGHͺo7kʻ:HAq)u9tA۬霒G""R&Pfͺo7S"#fdķ/^Hafݷ5M) zvjSa&-4Y KST>zp xʧ,z)HaP7A5 :(HnkJIRP7~>hۭn:n/}&S嬸H1Y.K'~"[lRZnq>yP~LǮq-bCS"{Vm9 ip &PJA]$ͺo7S"Q)>2|ĊWV.KFI^Ί?\S% e۲HA]$ͺo7S"s eq7 `TVCSRIA]$ͺo7S)˒Cy)-4Y"oG Q!M4c}TJarM]$T<'RPqq?Ela+)\=HaI9.K'~"[qox'&eݏE=A1F2V$ì`/[ׇr~ۏ]?&c׏㸖S嬐Ha~Ja0R[,BȠb eٔ0RL6-izSh+MoR>A Z/TA5EjtOK)h2nrFdpb(Φ,uY6/k)hZN M)RдV ꋉF #ŬeIB|"[qox'E~ۏKa0Rs^AvPA)Kax'5[ZeK )RPz\q=-z\q=H5嗴y|,z"m5;[]y3\SyS5[Z} )ZXf5(ER'kʷ&2X~5r<8SƊWV5[Z)w ;OߑkE}qMR)(i^֮PYה9Sa&HaP…q5?s&g;V0RPӯׯ?~o.b{XT&2+y*p*hаf)I} moV #&.x"<}i<`wv1Q/QWt6XÉl.EB9QK.p2<] >@hI]D].NCH.m~-l *,9dGs fK""a961/8/2K >(YÊh%tf8_|EF׈劐H2!<Va10#1Xܺ7bb)xi1- cPa"Ә,;axEFka#l K"a961/8/2XJ~'lF z/YZxK/='.2pN)e8qbopQn^Eŧ%`pR+YkߢpDi.6Eŧ%Ժ7R+Ykߢp؅Di. a#l0Ef1d1s^Sŧ%lIq \"#3݈sʜ6?-Lw O7Z\Z҅E~ŧ%EcqtG'n ŧ%m7#\OKvqx+^Ci ~Q5.+(>-a~`01Y 7q$|n)˄oF\yE uP|Z~m`p-RT|n)˄˷P|Z=[Rܭ,6qb~o| ŧ%|N w&;%pb~[Bi `p.*fj]Ŀq xrm[%p`w!fa 4YN$'R; If key pressed, then check for abort CALL BDOS ANI 5FH ; Convert to upper case CPI 'C'-40H ; Is it CTL-C!9"1:2 >AA_8 <~8 Uploaded to Piconet 001 (415) 965-4097 Type ^S to pause, ^C, ^X or ^K to abort wait a moment...:==2!" h ++ SOURCE FILE READ ERROR ++$!~hG ::I<2xP=:>E22PR2P2::<2::mx2 —:ʍ2*Ò: §.'+::͍4:xE,xEɯ20::<2:O:1 x_a aaCaKaXx  ++ ABORTED ++$+~ʉ |:0ʵ156  11 3122400 bps   8 :_ :_*~q#~9**"*#"#~q~ \0:~8 :E"ԅ(>mAi li?-(Se8Bi Oqg@OK ne8%pOSH G7pS)0P2nj.pt 7}Y@i S=딄gOKx}08K G7pSlYŧ%`C19&82P|Z_ 8?'疲L-e@i ~0ؒ"#CĹ˞oFl3Mf"KFC~6FgeݔFE1A/ ]񆐒 /[%LӲBݵn˺){T{aH -)n:`YڍO-6y#tcH? ?NU[/0ؒbOE%+ ]=~jJaH5YZxS8bvC5!oj ڲn{ajSS C/SϘ9~>#ECmY7嫰n˺)OM) N.^b ~n>#EC6mY7t)!]CT_U.DuqA?o0.z&0tN-)^nBb[%6)Ya=v0XvtR$+8b8K2n݈Neᯔqű/ EW.^" USrÃ0~-)RT[FYahf V%a#l 8/2uExi1-&\4&EEl`K,j,Oٵo1좇jr6:[a]PWi_[R[F<-f>R" ?70/ja]Um0tNVa"faawHCW{R5tM寪0ciu`~YkE]OV{Xy+ `3b N::8 D/U Filename Size Speed :8 Date Time Uploaded by 8Uploaded by Date *|\0||\   [End of listing]$8 ++ FILE TOO LONG, NEWEST ENTRIES LIKELY NOT SHOWN ++ h_  ++ NO NEW FILES ++$XMODEM LOGvXMDEL.ASM[  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGoHIJKLMNOPQRSTUVWXYZ2<]9 .^<$Lsa# >[0R.&B 190tS<eݔ0؏VH? ?52u1Q"nIJ08 omyR" _Y~Ql|*})l۲n?߁?z_uEe0K΄(&g!Ң- ;]/_~*E1XAf=fE!lDuE8L]LԅHS;865Ж5E[~!-_{T* ޒz1d1K昹IڍO!_m`%1X܅). QMvSȗT6%PWa)davCW/J) I|A2uG7*Qə{HhKaja0.zY0 xN u(L=UZ0tNVm0<>6o|`Kb DG7P1Yi/hC8 CW{R5tM寪C<3E>T{a#l 61 gG7n:ciUW0衫2:[a968bv[@0衫Nu75J iFMUWJxG疲La)aF; 5`Xi8oNWxG.^]7ϧ;PW3x󢄣 gf1dWZwSbSaj`0f7a! O-%RV:nȯ qa >! OP0X$f#YHQө0 XW56y#nddq cxn_.ax|ئ `? eO/g[-]Lq9 CP ޛԿGA+N6P C[~9|,dT+T ]L4ka#)Xn<l7P%))˒Kd>eF`_@] ޒnXajTzZ(:~{ )#TaPW3%e* ySC `*X8~0ˍ e,jВb2[2ah 6 d"80ϔe% ߄ 0e}T6o C50ҙ͋"0RF"<l& Ƨ/˩l ,#=)d1-eΗ-࢒d>ePW\bF* ǦZڲ̛`+.#8$'{;i m7Vu]Ԁg:CZ`[K1hөnmzӲ/,Ƒ,&,Y~u0xK"ܭ,$gaj!_ݦ)``]<-oHRM{6XAmLC$|pŒvax|S?G| /I1AWd1+ ޛmtEo^oF6Wwplj-krm 溢0,Ã0Lva~{0)`# ]=) 'QQiR2! >-0X9|E! ySC- O-%~Bw%ԕ, ӲFƧtr[ C=FڍO)`# b ߄6? ar˲6? aM.; >(?-(SWxP qxDÈ$luޔw0- laZHaZX 좇m[%V{F ^d)h. ]=Ӽ'ySGO"BT$ I| `^d)h^(nEg&Xi Cᷫ .7pq:]0tS`SJ! OPn`SJax|z7=~*E܅..H/:m ޒoHR CZs<,%ÂmnPtQ -Y `u=UZ0.z/ aja0M 0eMhnG]ax|2ͷ uEQf=tUZ0X$#S.&B T3 u.&0cim) ]=Ӽc_ Cׯ˦+6Eb4y_~9߄6X$f#YtC$!dsD]8.|[܁e90 +/ ۏ}2ͷŽ0B,Ii-`vC]0LvS. ]=˲40L0A* S>F| nuޔqጙ&gaj8%~*E{HF8-|ziZRax -|* ú CZcY~u C}e) :?CW{_B|0L0LkahR\&lɺx,K. uESԀ}&lc_O%3eYrI疲Lf=td]Tm2 0Xwb2ܺ7i CW{d]T74KSuR5tM寪0O-0 CS7a#l .{F 0Xwb2l]ͮ;]UiRJi lؗk*U~Ŵo uޔ¶跷7m=^8T/asᛰ68Hx.*ڰP ?ɺfj]SpQi3MvϸLwAؠp 8FlH6fw0DQW~*&'*-R{Xy+l.|[ށOkHO(&gBKZP4! AOP`? eO&À.[\aPL΄7AW82L2甩qtaL΄Iىvnt46=l_dXB h)&g0qt CZE[~ga]" ]=Bf=tUZ0@Jt18bv[@=U aja0cim ` <-f_|A xi10.z誦ֳB{Xy+ c_ ߄6RnddEҥ˔,j]YH;0- 0- la_@QUbE X,v0.z˷߭SB 1  CW{4oa'ÔO ÔO(oF<K =-G7}q8bCվWj_!]þWj_}վWj_pZkW__|9Tj_}^5}վWj_}վ .5 vaX#<-f>ENe[4wa`0duo}p -F̛5셍嶼s.]L\$܅ET˗w.RtRt#=Ηe6wzyuU4w ˲ }u?7a# i =&3oр&ga#l `,Ƒ,j@z&,ܾaț[ۗﯿ_^/OK`:%Y#Y4, e˫*l0ڲnJ A public service announcement from the Tampa Bay Bandit Board RCPM I am often asked, "What's a TWIT?" ... my answer is: {}==================={} || A "TWIT" IS A || {}==================={} Caller who keeps signing in with phony names to get another 30 minutes before being asked to sign off. Caller who won't bother to TYPE the .INF (info) files to find out how to use the system properly. Caller who insists on TYPE'ing files endlessly, especially useless ones, like the LASTCALR file, XMODEM.LOG, any programs written in "C", and even *.*. Caller who does endless DIR commands and never echoes anything to the printer. Caller who tries XMODEM R to send a file (about 50 times) Caller who keeps trying to XMODEM S RBBS.COM or other .COM files. Caller who doesn't know that CTRL-C aborts almost everything including DIR listings and tries every other key instead. Ca!9"1{ XMDEL - rewrites XMODEM.LOG :X{Keeps "R" and "P" entriest{Keeping only "R" entries{ Continue? (Y/N): _Y:2p >AA_{ -<ʑ:] !\N͈!-N ͈2Z2n!"z!"xNN<ʺ{ wait a moment...-N!~~{G ʅ:oq<2o:xeP2qxR2qq2q:q~x, 72o*r#"rͨ:q~*t#"tx _ CKX ++ ABORTED ++$  |{0  :p_ :p_{ *N ++ DISK FULL, ABORTING, SAVING ORIGINAL FILE$~ #~|~#ˆ ++ No files transferred recently ++$ NO DIR SPACE: OUTPUT$ CANNOT CLOSE OUTPUT$*z*x}|>!"x*z{z0*vNA*x"x!"x*v*x#"x{N++ SOURCE FILE READ ERROR ++$*x}‡"z>{-N<{ *r{ original lines *t{ retained lines *t}N:W$ller who repeatedly tries to TYPE .LBR files, and leaves messages asking why the machine won't let him. Caller who tries something like this: A0:SYSTEM>apple //e with a hayes card and cp/m APPLE? A0:SYSTEM>yes an apple //e, what's wrong with an apple? YES? A0:SYSTEM>yes, I said yessssss!!!!!! YES? A0:SYSTEM>list LIST? A0:SYSTEM>load LOAD? A0:SYSTEM>fre FRE? A0:SYSTEM>run RUN? A0:SYSTEM>menu MENU? A0:SYSTEM>exit EXIT? A0:SYSTEM>quit QUIT? ++CARRIER LOST++ and calls back several times each week to ask the same questions. Caller who leaves a message on RBBS and says you should have a message program on the system so he can leave messages. Caller who discovers CHAT and tries 300 times in a row to summon an operator even after being told, "Sorry operator is not available" Caller who tries every possible combination to change user areas and just can't seem to remember to use the colon ":" Caller who leaves a message on RBBS asking !._͈-N_XMODEM LOG $$$ L2 (C Linker) v2.1 8 7 Dec 81 #define FUNC11 0, 0 #define FUNC12 0, 1 #define FUNC13 0, 2 ... OvlCall (FUNC11, arg1, arg2); ... To make a MAKOVL.COM: cc makovl.c -e4100 cc chario.c (if necessary) cc scott.c (if necessary) l2 makovl chario -l scott Good luck Scott W. Layson Mark of the Unicorn P.O. Box 423 Arlington, MA 02174 /* TELEDIT.C v1.3 (see TELEDIT.DOC) Modified for BDS C v1.50 by Leor Zolman, 10/82, 2/83 A telecommunications program