! "W N F=    @ #D  D ҃TT ^ B ы e@W 0 ,"& 7    " 7 -  X e5PߋRTV`RߋR RT `Re `R7 t*p ȋ@E A Ze   ?    7? eEadb/adb1.og #L?adb/adb2.oY Msadb/adb3.o PMYadb/adb4.o) MKadb/a68defsS 6ubadb/adb.h4 S 9uadb/adb1.c:FS ;uadb/adb2.cAS =u^adb/adb3.c*S @uHadb/adb4.c\S Bu;agen/aabal.c2C 3,Uagen/aabin.cC 40'Uagen/aahash.csC 53}agen/aasub.cC 66Ragen/al.c#a 7zagen/ay.czC :IH;as/as11.sC Sas/as12.sC Vas/as13.sC Xٌas/as14.s C [uas/as15.s,C `0as/as16.s3 C d"as/as17.sC jas/as18.sC oas/as19.sC r@fas/as21.s C as/as22.sC as/as23.sC Nas/as24.s<C as/as25.sC  as/as26.swC ias/as27.s7 C Մas/as28.spC as/as29.sC Qpaslib1/atan.s C aslib1/atof.sC aslib1/atoi.s&C aslib1/compar.sC ~Uaslib1/crypt.s"C (aslib1/dpadd.sC aslib1/ecvt.sS 4uaslib1/exp.s}C *gaslib1/floor.sC aslib1/fmod.s C aslib2/gamma.sC aslib2/get.sC baslib2/hypot.sC aslib2/ldiv.sC aslib2/log.s C haslib2/mesg.s>C aslib2/pow.s(C cYaslib2/put.sC Yaslib2/qsort.sC (aslib2/rand.s"C åaslib2/savr5.sTC #aslib2/sin.sC Yaslib2/sqrt.sC aslib2/switch.sC OEaslib2/lnxx.s ]bas/bas0.sC  bas/bas1.s C çs"bas/bas2.s C ħ#bas/bas3.sC ŧi bas/bas4.sC ƧI$bas/bas5.s C ȧ bas/basx.s.C ȧ+cc/c0.hC %cc/c00.c 1C '-)cc/c00.o4C *Fcc/c01.c "C ,a7cc/c01.o"C .s*cc/c02.ch3C 1%cc/c02.o2C 4cc/c03.cY"C 64cc/c03.o,"C 8(cc/c04.cC :j@cc/c04.o4C <2cc/c05.cC >ZCcc/c05.oXC ?7Scc/c1.hC A#cc/c10.cUC D (cc/c10.oLC H4cc/c11.c.=C K[Qcc/c11.oRC Ozcc/c12.cF;C Rcc/c12.o7C U,cc/c13.cC W%>cc/c13.o C X|5cc/c2.hC Zcc/c20.c-C \;+cc/c20.o1C _cc/c21.cE&C a)U1cc/c21.o)C c=!cc/cvoptC eRcc/cvopt.cC fZ˓cc/table.i2\C kcwMcc/table.o ?C n"dcc/table.s+C psclib1/abort.siC wclib1/abs.sC 2clib1/access.sNC clib1/accnt.sC clib1/alarm.sC ۵clib1/alloc.s C Lclib1/atof.sIC @qclib1/atoi.c C yclib1/cerror.sC ¨xclib1/chdir.sC èclib1/chmod.sC Ĩclib1/chown.sC Ũݴclib1/close.sC ƨclib1/creat.sC Ǩclib1/crt0.sC ȨVclib1/csv.sC ɨ!clib1/ctime.cC ʨclib1/area.c S /ubclib1/croot.s clib2/dup.sC ̨\clib2/errlst.cn P'clib2/execl.sC Ψոclib2/execv.sC Ϩclib2/exit.sC Шcclib2/fcrt0.s C Ѩclib2/ffltpr.stC Ҩkclib2/fltpr.sC Ԩclib2/fork.sC ը`uclib2/fstat.sC ֨gclib2/exect.sS 2uclib2/elog.s& Mclib3/getc.sC بzclib3/getchr.sC ٨Aclib3/getcsw.sSC ڨlclib3/getgid.sC ۨ:clib3/getpid.sC ܨ4clib3/getpw.cwC ިclib3/getuid.sC ߨ?clib3/gtty.s0C aclib3/hmul.s9C vclib3/hsw.sC  clib3/ilongops.sdC clib3/itol.scC oclib3/kill.sC =zclib3/ladd.sC clib3/lcall.sC bclib3/ldfps.sRC clib3/link.sC %{clib3/lock.s(C nclib3/locv.s/C hclib3/longops.sFC Iclib3/ltod.s?C vclib3/ltoi.sgC rclib3/ioctl.s  S' 1clib4/lseek.cC "uclib4/mcount.sC #clib4/mcrt0.sC $_clib4/mknod.sC &3clib4/mktemp.cC 'clib4/mon.cCC (w#clib4/mount.sC *-clib4/msg.sC + clib4/nargs.sZC -clib4/nfrin.cC /nclib4/nice.sC 0=clib4/nlist.c/C 1 clib4/open.sC 4pclib5/perror.cC 5|clib5/pipe.sC 6 clib5/printf.s C 7clib5/prof.sC = wclib5/ptrace.sLC >clib5/putc.s C ?sclib5/putchr.sIC B clib5/qsort.c,C Dclib5/read.s#C Gclib5/reset.sS OuHclib5/retrn.sVC Jclib5/rin.cOC K.*clib5/rsave.sC Lclib6/sbrk.sC Mclib6/seek.sC O~clib6/setgid.sC Prclib6/setuid.sC Q}clib6/signal.sWC Rclib6/sleep.sC Uclib6/stat.s"C Wfclib6/stime.sC XQclib6/stty.s0C Y_aclib6/sync.sYC Z9sclib7/tell.sC [}clib7/time.sC \clib7/times.sC ]7clib7/umount.sC ^8clib7/unlink.sC _A clib7/vcall.sGC `clib7/wait.s,C !aWyclib7/write.sC "bcmd1/ac.c9 c.cmd1/accton.cC mhcmd1/ar.cB,a n&cmd1/cal.c* a مcmd1/dcheck.c vcmd1/cc.cSB cmd1/diff.c-a !Ӵ#cmd1/check.cC ^cmd1/chmod.c}C cmd1/chown.sCC jcmd1/clri.sC cmd1/cmp.c-C bcmd1/col.cFC 1cmd1/comm.c#C cmd1/cp.cC Ëcmd1/date.c cmd1/dd.cC dcmd1/df.cC 6cmd1/cat.ca cmd1/cpall.c 5cmd1/chroot.c ewcmd1/dsw.s C $ Acmd1/du.sAC %‡cmd1/dump.c!S s;&cmd1/diff3.ca #&hcmd1/diff3.sha (6cmd2/echo.cRC )79$cmd2/ed.c+Na 8cmd2/exit.cC -`"cmd2/factor.s C .acmd2/fc.ccC 0g`bcmd2/file.cC 1ucmd2/find.c4$a wZcmd2/getty.c U'cmd2/glob.cUC 6cmd2/goto.c dcmd2/grep.cC 9]cmd2/gsi.c{a ٬jcmd2/hyphen.cC =cmd2/icheck.c!C ?cmd2/ichecks.sC @cmd2/if.cI a TOcmd2/init.cR Fzcmd2/ino.cC Crcmd2/iostat.cC EYcmd2/kill.cNC FQcmd2/errdemon.c cmd2/errpt.c+ 1cmd3/ln.cC H:cmd3/login.c !*cmd3/lpd.s C K(cmd3/lpr.c C L-cmd3/ls.ca 3(cmd3/mail.cH A'cmd3/mesg.c Kcmd3/mkdir.cC RMtcmd3/mkfs.c C SOcmd3/mknod.c3C T`1zcmd3/mkpt.cC Vb{cmd3/mount.cC Wj`cmd3/mtm.c C Xmcmd3/mv.c C Zsvcmd3/nice.cC [z+cmd3/nm.cC ]{ycmd3/nohup.cC ^scmd3/od.ca ق$cmd3/ncheck.cr% ?cmd3/line.c: cmd3/mvall.c %cmd4/passwd.sC bcmd4/pfe.sC ccmd4/pr.c cmd4/prof.ca ٷ}cmd4/ps.c cmd4/ptx.c C jIcmd4/pwd.c cmd4/reloc.c C l"ncmd4/restor.c"S sŜcmd4/rew.sC ojcmd4/rm.cX 1cmd4/rmdir.sC q]cmd5/sa.c $cmd5/sed.hC u cmd5/sed0.c0C x cmd5/sed1.cC y&cmd5/sh.cT 6cmd5/size.cC ~acmd5/sleep.cC c@ocmd5/sort.c6a dcmd5/split.cC <`cmd5/strip.sC Kcmd5/stty.c X'xcmd5/su.cC Mwcmd5/sum.s9C +cmd5/sync.cC  cmd6/time.cC cmd6/tr.c) C ncmd6/telinit.c  cmd6/typo.c1%S x[cmd6/umount.cC cmd6/uniq.ca ٴ{cmd6/update.s_C Νcmd6/w2006yUC cmd6/wall.c. cmd6/wc.cC ocmd6/who.cq ؁cmd6/tail.cY a ~ cmd6/tee.c@a cmd6/write.c $cref1/allfuncs C <cref1/allvars C > [Tcref1/getfcrefC ? x cref1/getfuncsC @ cref1/getvcrefC A Tcref1/nicecref.c C C 4cref2/acts.c7C F Pcref2/asymC I' @cref2/atable C K) lcref2/ccmn.cuC L/ .|cref2/crpost.c_ a 1 cref2/csymC N8 cref2/ctable C P9 blcref2/dr.cC R@ ?cref2/ecmn.hC UO wcref2/econs.hjC VQ \cref2/esymC WR cref2/etableC C YT ncref2/ind0.cC [Y cref2/ind1.cC \d Ģcref2/ind2.c$C ]l 4cref2/make.cv C _n Ӏcref2/mcons.cC `s cref2/mtab.c a t ?cref2/put.c C bz cref2/upost.c C e| ocref2/ataba ܂ ڧcref2/ctaba ܄ ԧdc/bc.clYa ن /dc/dc1.s7yC ڧ .dc/dc2.syC ۧ )dc/dc3.sC ݧ )dc/dc4.sC ߧ )dc/dc5.sC  dc/lib.bIC " #delta.oX: yS& fed/fed1.sC D {fed/fed2.sC G fed/fed3.s`C S font/B.cGS z\ +\font/CE.cLS z` font/CK.c[S zd font/G.cGS zh Wfont/GI.c@S zl font/GM.c[S zp tfont/I.cES zt Ufont/L.c^S zx Qfont/LI.cfS z| Yfont/PA.cpS z Pfont/PB.cS !z -font/PI.cS $z (font/R.cGS 'z Kfont/S.c S *z FHfont/SB.ccS -z 6font/SI.cjS /z "font/SM.cdS 2z font/UD.cZS 5z )}form/form1.sDC 駨 0[form/form2.sC ꧭ s^form/form3.sC 짯 Zform/form4.s C aUform/form5.s&C 粒 \)form/form6.sNC 4fp/fakfp.sC -fp/fp1.sC Y fp/fp2.sC  e9fp/fp3.s9 C  2fp/fpx.sLC  <4 w f ff fff ef& e5u   umum u A@ww w ww |f h& ^ % TwPw LH B@:v72w0* $"v7w@"  e%%@7%@7w Z " P~x7wl b^VR 7<%   7  7  F" 7  7 " 7 N   7  *7 &   fw h d` wXw T " #:x 7, ( ` >7 % F"  %%_^% % %%7 _^  e7w|zvp7lwjhd`Z7VwTPJmFmD@ 77P L%D # ,(> %%_.E%_.E%_.E7t77wt77wt77w% |vtn je 7\wZ%RNHD>m:m8@ 74w20 *  7w%e@ 7www f 5  f ww ; wpw f   wJw F B7z2 6).&" %  7  f  ȥ ? ww \ v  ww Z%\ P w'w DË (%  fD-wZ  v %"@ w .A m m@ 5u xxvv fA@ww C 5uxxvv fA@ww -# ww | t    w^wX \7N HFDB<:860.,* %, \   7   v   7w @7E r eA! yU5  %* ^5 U @55%=z 5 7 y  f5555e  \ Br e@  >%?@ /@ ~N# _6wf_V fHD@ \0.,* \  7wN %75uwN f& %75u A@~B C @@7 rw n f 7^w\ T wLwH@$#f60 e_6 fJ \%#f eNffe e7 wwf e f > f&f` eTP+# Nffe e \  ww_6 @ | 0#f eff@ xe n7  45@ 5  m~|zvH@ mh@e &V _ @ 5% 4.Btr2) $7 R D!7 H 6    7 7  6#  f X%;_ _ _  _ _ w  _u N \ZXVR  B:# .*5 = =@5 d 5 AWp u@e5`@5 d  N f ff e5@A @7ww~ x  7 lwhd f   F 7>w< 6_ f_w " _uuA Z A @@f @P5 a5-N %57~N @ f& %7d\wVRL5uFN f& %5N f& %5 @w  fwwu 7 aE# @  o_* xNJ# NM#P#f lf e7 ZV 7NwL  _V#f 4. eN[# ff`# CNE NE NEf#  ' 7wS@ @ Nrl %E5ZT@A e@ @7>w8w4_Nk#ffp#ffv#N|#_ff#_N#_ff#_Nf& %7 _N#_ff#_5uu5&# ve l_uu5&# Ne D_ _7 0  @ "_ _upN  7w_N N f_w  L  5*   | ?t f### e *% f! Ne 5@-% # ww E% %~%@%@@`A@x# N ww  . N 5 _zv $ r e A! yNU wmBwm>w 8NU A@ 7wNU ff eNU ff eNU ff NU A@@ A 7@w@_xNU w]nw]j_x5 f P@wHw D  7  y NU  %77wwNU NU   NU @ A  \)  f N | w 5 *  _ ._R7NJDE5u7 407*/ff % "wff %7E5u   f ww j  8 <ff %  f  5 f @7 LHB7>w< 6w.h d #R    .:_\7 7 0  5"f  e (5@- fA 7`xw`vw p "  d .%  8_ 0__ 755  5&55 ,eA5  d 5u5@ 57_"_+ v   mj7hd^7ZwX_^<& 5@ 5@ 5% t7 7_ f_'.77 7 % v7w5Wt 7PwP _@  f  p _w f%ԝ   %w:w 6 0 ,5 Nf @w w 09 af ww @ d @e@ew@  w 09 ww xaz AZ wRw H\ _n b d  wN  w N d @e@Ee wN   oo"= "^i= !!(!_eof _eqforma#@_stforma#_regbuf _uregs _dot _ditto _dotinc _lastcom#@_var _locval _locmsk _symfil#BL3 _corfil#DL4 _pid _expv _adrval _adrflg _cntval _cntflg _printbu _printpt _errmsg#FL5 L6 L7 !L8!L9(!L10L68L67"_read L69^L70^L10001L10002L10003L10004 L10005:L10006BL10007bL10008jL72_freecel _getcell L73_symset L74JL20003L75TL10009>L100104L10012@_symget L62p~setcortL78#L79L80L83L82#L84.L10013L10014L10015L10016L10017L10018L77:~create>ffd_creat L87p_close L86l_eol"v~eolvcL10019L89~rdcL93_readcha"~readchaL95L96*L97L100L10021L10022L98L99_nextcha"2~nextcha2L104NL103J_quotcha"T~quotchaTL107nL106jL20005h_getform"|~getform|fptrdeformatquoteL112L10024L10028L20006L113L111_inkdot"~inkdotnewdotincrL117 _dekdot" ~dekdot newdotdecrL119Z _endline"f ~endlinef _charpos L120| L122#L10045L10046L158 L169 L159 L148 L170 L178 L10050L10051L10052L10053L192.L190$L187L188L181ZL186L138f L140| L142 ~command bufdefcomregptrfcountlongprsavdotamapwsavcsmapwformateqcommodifiersavlpitypeptypeL129 L125 L20014 L123 _expr"\L130 L131 L132 L133& L20007D L135< L10049^ L139 L20009t L144 L141 L10030 L10031 L10047 L149 L10032 L10033 L151H L20011& L152T L153j L154 L155~ L157#_printma L1366L20013 L194VL160 L161 L163 L10034 L10035 _get L165l L164 L166 L167 L168$#_psymoff L20016 L171 L172 L174%#_exform"L175n _put L10037 L10038 L176+#L173 L10040L10041 L179,L1800#L10042DL10043H_scanfor"x_getreg L182_ptrace _varchk"L184L200152_unix"6_printtr _subpcs L1916#L10054p~scanforxifpicountfcountsavdotinitfpmodifieritype ptype L196L10057L195L198_findsym L199:#L200ZL20020L201`_digit"dL2022L203L20018L2058L207L208L10058L210L10069L224L290*L283L288L289$L247(L243L275\L279L2720L282L269 L263L232L250<L229pL240L257L259L287L234L273PL277lL266L236L261L238L255~exformifpfcountsavdotclongprwfpfwwxmodifieritypeptype L213L20023L10059L10060L10061L10062L10063(L10064,L10065@L215bL216L217L20022L219L220 L221L100668L10067<L222XL223E#L230J#L20030xL233M#L235P#L20026L237V#L20031L239[#L20033L241`#L20037L244_printes"L245 _printc L248f#L251L20025PL252L253zL254L256k#L258p#L260v#L262|#L264#L267#L270#_printin L274#L276#L278#L280#L284L20028L285L20041 L20039~unix6statusargpunixpidrcL292JL20043F_fork L294L297#L296#L295#_execl L291L299L301_wait L302L303#~printescL10070*L305PL100718L10072DL306#L304XL10075 L10076 L10077 L10078 L10079 L322L316L314L317:L313L319L315L318\L320~expr\alhsrc_term"L309xL20044L10074L20046L20048almul L10081 L10082 L330PL326L328L327L3296L333h~termaL10083L20058_chkget L20051L20049L323L331v_item"|~item|adbaseregptrhexrealsavcfrptsympframe_symchar"L335_readsym"L336L3376L20060_findrou L338<L346L344Z_localsy L345t_lookups"L347L20068L349L334L10084L10086_hexdigi"L10085L350L360\L100894L10088:L10090JL10091FL351L20062P_convdig"(L353~L10093L10094L10095L355L20064L357<L20066.L362tL364L20072L20076L20078L368 L371L20074L374L375^L20070"L378>L10096LL10097TL381~readsympL386L387L388L20080~lookupssymstrsympL391L392L390~hexdigicL10099 L10098"L10100L394~convdig(cL396PL395LL20082D~digitdcL10103xL10102~L400z_letter"~lettercL10106L10105L10107L401~symchardigL403L402L20084L10109L10110~varchknameL405*L404&L20086fltused 80~lookupssymstrsympL391,w d  @ r eA! yJ5 % %< P M@@a %? % @@m0%< fe 7Z%7 T fe 76 fe 7 &  % w7  P @7  @7 5 %#@t  % 0WNm @tf& Ze  8  8  .(    _%F  "_  7E5u7 `7 _ _ zv_ff d%5 A@e@ 5u ff %  %C6>eu ff % %5  7 N ff 0% wtff %7`XE5u _` _`_  5_ "_ _%#%$@7  %f %  z75u 7 _ v |ff %5A@e@ f& %5A@e@ f& %5 %A&fffff e%  A@ f& %% A@ f& %%  _^ r A@ f& D ewVwRN@`5& l @e70&( %5 w %5eE5@tE5@ @ @ "  A @mAm@ f& %, e@  wD_F2 2 _ %W ^7  Hee 5@ J _w @5o -fc %@f&q ze@f&| ^e@ f& Be@ f& &e@f& e@f& e ww   5   t0 t05&& e %wvw r  m5& %%f l  e%ڂ @ww  5@-we% w 77w He %& % wzw v5 jhfd@ r eA! y @><:6 3 _N   3  J  L % J33?e 5 =   ~= t _ d ^ N  *E5 .4N z .-  U R 5    E  v ww  w@w |vtrplb e F e *2 Z bN&  e j De 70 e%:&e    5 ew 45 tpjf ` @wTw P L & B e7 2. J ww   7$ & & & e   | R :% 1 j  0~ 7t p j  X  <L e7e = eNen wdw `\ L-J w@w <8  &$ eJ w w 2 - & e3& e L d HeJ ww  Ne -r%f %7 RL>@E%#@E70 f 5 i  7 @t7%  x 7   ww   te & %WtA m@  %   & % 1  %6wPw L %- p )2 %%f %%fe %%@wNff ew  * x' n %%feT %%w- wtwl w d | 7  7w@w u-u- u- u- ww A@ @@@5A@C v@5ff %% ff %% ww Nf  5-x N wPw L P C>@~6<85%5%% w wm%%  me77ww w Nww  5- ff ~e N N wJw Fw>:45u( 5 _@_5%=@-275uA@@A 5 u u-u-A@@A 5u5e   ?At@ r7jb5uXR@A 7DwB ff .em&m$@ f& e  %@ww   w  f& emm@ f& e   e% w vrpnld\VR @e 7>8e@ f&* eww - L     e w w  %5%  r Wp eww|  $(;BLYiu&08>       ,$,H,,* , ,$,H,6 , ,*,6!&!& #0   0  0 pspcspr5r4r3r2r1r0hangupinterruptquitillegal instructiontrace/BPTIOTEMTfloating exceptionkilledbus errormemory faultbad system callbroken pipealarm callterminatedvariables = %Q text mapdata mappcs id = %d no process %s%.8s(%o,%o) %8t%.8s:%10t? %o %.8s:%12t%o %8O:%8t%-8o,%-8o,%-8o ? %8t%8t"%24targs:%8t%8t%obreakpoints count%8tbkpt%24tcommand %-8.8d%24t%s%12t`%s' -b1 = %-16Qe1 = %-16Qf1 = %-16Q b2 = %-16Qe2 = %-16Qf2 = %-16Qfpsr %o fr%-8d%-32.14f %s%8t%o%8t:%16t%d: killedbreakpoint%16tstopped at%16t%s: running %s: cannot execute %s: cannot open %s: cannot create cannot set breakpoint: %s - core dumped%s /dev/swap/dev/mem%.8s+%o%Q%.8s+%o Y ( I YYY ) xx xx9 HX8  8 I h8 8  h8  8 8  9  8 )))8    8 8  8 8   8 9 9 9 9 9 9  I 8 9 I 8  I I   iiiiiiH I   i)i))i)i))iY  8     8 I )))I i)i))8       I I Xi9IXX  8 II I YXX 8 I I I   I 898  X8 I I 9( ( I  I( 9I I I I I I ))))) YIi XHI I ( ( I h8 8 I yiii)))iiI )))9 h8 8 8 I yy9$iihI yyyI yy9$iih yyiiiiI yyyyyI I _int2ws _lengws _longws _realws _txtmap _datmap _symbol _localok _lastfra _callpc _symvec _mkfault _executi _line _infile _outfile _lp _maxoff _maxpos _sigint _sigqit _octal _symbas _symcnt _symnum _localva _symrqd#_symbuf _symnxt _symend _bkpthea _reglist#L1L2L3L4L5L6L7L8L9_frnames#_lastc _regbuf _uregs#_fcor _fsym _errflg _errno _signo _devswap#_swapblk _proctab _devmem#_dot _var _symfil _corfil _wtflag _pid _expv _adrval _adrflg _cntval _loopcnt _cntflg _signals#L10L11L12L13L14L15L16 L17$L18(L19;L20BL21LL22YL23iL24uL25_printtr"L10017L10018L10019L10020L10021L10022L10023L10024&L100250L100268L10027>L135,L66L48L77$L73L46L62L54HL103,L52*L97L50 L125L75 L45L316~printtrcsv comptrifilenamenargargplinkstatwordsymphiloframemodifdynamlimitindexbkptrL27L10016._rdc L38XL33R_iclose L35_oclose L36x_error _readcha L40_open L43_creat _seek L26cret _done L10000L10001"L10002:L10003@L55_prints L56TL10004pL58L10005~L10006_printc L60_printf L63_printma"8L64L67L68L69L70L71_flushbu _printre"L10007L10008_printfr""L100094L10010FL78`_findrou L80L83_get"L82L20001L20003 L86L88tL87L85L20005.L90L91fL92L94_localsy"_symset"L98_symget"L10011L101L10012<L10013NL20010FL20012hL105\L106 L107L109 L110zL111pL114^L113L115_valpr"lL116L119L118VL120L121L20007tL123,L1262L127L129&L131WL132^_psymoff"HL133 L20014~printma8samapfileL10028PL138oL10029bL10030^L137cL139qL140|L141L142L143L144~printfr"longprifL146L20017:L10032HL150ZL20015jL152~printrepvL20019L157L10033L10034_printpc"$ _getreg"~getregregnamregptrregnxtpL20021L161 L158 ~printpc$ L164_chkget"_printin _subpcs" L10038L10039L10040L10041L10042L2010 L199 L173 L188 L192 L169 L194 ~subpcs comptrexecsigcheckmodifbkptrL10037 _scanbkp"L170 L165N L174 L175 L20023 L176 L179< _getcell L1802 L184h L183 L189 L190_endpcs" _setup" L1668 L20026 L10043 L202> _runpcs"z L203L20024B L195 L20029 _getsig"R L200$ L205_delbp"~getsigR sig_expr L10044t L206p ~runpcsz execsigbkptrcL208 _ptrace _setbp"L209L210 L20030 L10046 L211 _bpwait"j_readreg"FL212 L10047` _command L213v _execbkp" ~endpcs bkptrL216 L218 L20032 L220 ~setup _close _fork L223P _signal _doexec"_exit L222 L225b L227 L228_reset ~execbkp savepsbkptlocbkptr_gtrace"L231 L230~doexecpfilnamarglargsapL236L235~L238L20034L239L240fL234vL242(L20038XL200406L2469_exect ~scanbkpadrbkptrL249L20042L251L250~delbpabkptrL254L20044L256~setbpabkptrL259bL20046L261^L264LL265d~bpwaitjwstatexflgL267~_wait L268L269L2702L271 L272L273fL274L275i_setcor L277.L278xL266B~readregFiL20048LL285L20050~gtraceadrmodervalueL289_chkswap"2_read L288~chkswap2mprocL292L291_setproc"~setprocL295|L296_put"~putadrspacevalue _access",~getadrspace~chkgetnwspaceL300&~access,adrmodewfilew1rdspace value pmodeL10048>L10049BL302*L20054PL301RL20052VL304lL10051L10052L10054L10055L305L306$L10058L20056L10059 _chkmap"L10060VL10061Z_longsee"L10062L10063L10067L20055_write ~chkmapadramapspaceL10071L10072L10073 _within"L310L311tL20063L10074L10075L309~withinlbdadrubd L10077L10078L10076L314~longseefapageoffsetL10082`L10081fL315b~valprlvidspd_findsym"L316L318L320~localsycframesymflgL322_nextsym" L323DL324L20075,L20070L20076(L321@~psymoffHvs typewL330L331L332L333L335~findsymsvaluedifftypesymvaloffsetsymtypsymptrsymsavvalueL337L338rL10084L339~L340nL10085>L10086Plmul ~nextsym L344$L20078L343 ~symsetL347_symread">L346~symgetrcL350L351L352"L10090L10091:L3496~symread>symlenL354L353fltused L332L333L335~findsymsvaluedifftypesymvaloffsetsymtypph w DCe̥~̥_  ԢӋ w w 5  @ ȋ@ww _\@?h% X5 5 5 3@55  5      } @- N %    5 ww zww %h `wxw t\u@e5_@ `_%-l rNe n5.  Ne n5@e7@5555ue5 @5 D 4_V x @&f %_f _@_ f& ju ff@&f& Je_fff @%e_f @&ff Je ff jxN `_fu_feNefef=& e 5 -+? 0@ ?~ z  .j f @ R N  @0:4Ae@%7` e u ff j%5 #uTu   5ru@ ` ?@e5N <55 _l@55r `@ @ `@  `@ @e7 @ 5_ww Ne 5@a? %@a? %ww NN  ww 5 9AWp B`eu@ 5%0 @wFw B"@e5 %d@ 5- Nf& %5e @e@-= eu@ 0W@`? @e@-ww uu  A@  5u-Z +L H5 @@mBA A@pA@v5u % 5 @@m  @@me0? ww @@e5DAw 5~7 |xr &55w\XR V5x0#8 4*@e@-^= eXww  55 - 55u5u  5 555u u=e 5u@ 0W@`?n j@e@-wZw V RL 7 Dw@w <%6  , "wV*VVVVVV VVVV(VV VVVVVVVVVTV*VVVVVV`V~VV (TVV%s999999 999 99  9 9 9_int2ws _lengws _longws _realws _txtmap _datmap _symbol _localok _lastfra _callpc _symvec _mkfault _executi _line _infile _outfile _lp _maxoff _maxpos _sigint _sigqit _octal _eqstr"~eqstrcsv s1s2as1as2es1L10000L4$L58L100010L14cret _length"<~length<nsL8LL20001H_printbu _printpt#_digitpt _printc"`~printc`cdpqtabsposnL10\L130L14L20003L17L20L16L22L23_write L25RL200058_charpos"`~charpos`_flushbu"p~flushbupL31_printf"L10009L51L72VL58*L66 L52L53L68(L54 L49L55L45TL20021`L46~L47L56 L48~printfadjdigitscnsxfmatpreca1fptrvptrdptrrptrdecptlxwidthL34L20007L20020L38L39_convert"nL40L41_printnu"L20008fL42fL20012lL10010L10011L20022_printoc"j_printdb"J_printda" L20024L20023L20028L20031_ecvt L10002^L10003bL10004vL10005~L59L60L20010L62L10006L10007L64L698L70>L73zL75L77L20014L20016L79L20018~printda itvectimeptr_ctime L20033$L20035>_prints"X~printsXsL89N ~convertncncpL91L20037|L92~printnuknbasedigsfmatdptrL95L20039_ldiv _ldivr L98ZL20041.L10012LL10013P~printocjiosdigspoL101L102L20042L20044L20046 L109 L112@L20048&~printdbJfgkbase qdigsfmatdptrlxlyL116L120"L20055L123L20049L20053jL10014L10015_iclose"~icloseL125_close _oclose"~ocloseL127fltused 12LL10013P~printocjiosdigspoL101L102L20042L20044L20046 L109 L112@L20048&~printdbJfgk"Hw 57A@e@ f& %7e7& %5e7& %5% 5 %  55 f@E?% @E?% & w % & Nm ?77  %5% @ %%@e%ee7& % r@m@w ndw^X"e@ AA @@, @E5@ 5@ _ x  b N) D w@tEfE  b N@t&@tE- D @E 1 N3 E@t7 L I F:N , f& %77w=  %5 7 ? N %} 7 _@t _ _@ C & fx t f& je7d&\ eeNND _w 8NJ D NN D ww N 5UA @`e5P w eww DEEN %_V5n5* 5 5 n? W^e 7RwPfHD @ f& 6ee7.&7&w$Q 5% "$  f& %77wR 5&  eew   r e A! y S * X * ^ * D? &40 , f& %77wd %8&  eee @ D 0H @L PP `T X ? [ ?@ _ ? c ? g ? k ?@ o ? s ? w ? { ?@  ?  ?  ?@ ? ?@ ? ? ? ?@ ? ? ?  ?  ? ?@  ?@ p r t v                 # ( , 0 4 : ? D I N S X ] b h n t z        x     ?  ~               $ * 0 5 : A G N U \ b i o u { ~               # & @N^:  " *   RzRRmovcmpbitbicbisaddsuclrcomincdecnegadcsbctstrorrolasrasljmpswabldfpsstfpsststclrftstfabsfnegfsxtmtpimtpdmfpimfpdmuldivashashcbrbnebeqbgebltbgtblebplbmibhiblosbvcbvsbccbcshaltwaitrtibptiotresetmulfmodfaddfmovfsubfcmpfmovfdivfmoveimovfimovfomoviemovifmovofcfccsetfsetisetdsetljsrxorrtscflgsflgemtsysmarksobsplindirexitforkreadwriteopenclosewaitcreatlinkunlinkexecchdirtimemknodchmodchownbreakstatseekgetpidmountumountsetuidgetuidstimeptracealarmfstatpause30sttygttyaccessnicesleepsynckillcswsetpgrptellduppipetimesprofiltiusetgidgetgidsignal495051525354555657585960616263r0r1r2r3r4r5sppc%8t%8t,%8t%8t%s {; %8t%o%8t,(%s)(%s)+-(%s)(%s)y(((iiiiy(( 8 H  Hy)8yy8yy(iiHHyy 8 )) y)y))H H ()) )9 H )8 8HHH H )8  _int2ws _lengws _longws _realws _txtmap _datmap _symbol _localok _lastfra _callpc _symvec _mkfault _executi _line _infile _outfile _lp _maxoff _maxpos _sigint _sigqit _octal _errflg _dot _var _findrou"~findroucsv cframelastpcvnarginstback2_get L2L3L20001L10000L10001L20003L10002L10003L1cret L10004L10005_findsym L8L9L10DL11VL12_optab#"L13@ L14D L15H L16L L17P L18T L19X L20[ L21_ L22c L23g L24k L25o L26s L27w L28{ L29 L30 L31 L32 L33 L34 L35 L36 L37 L38 L39 L40 L41 L42 L43 L44 L45 L46 L47 L48 L49 L50 L51 L52 L53 L54 L55 L56 L57 L58 L59 L60 L61 L62 L63 L64 L65 L66# L67( L68, L690 L704 L71: L72? L73D L74I L75N L76S L77X L78] L79b L80h L81n L82t L83z L84 L85 L86 L87 L88 L89 L90 L91 L92 L93 L94 L95 L96 L97 L98 L99 L100 _systab#L101 L102 L103 L104 L105 L106 L107 L108 L109 L110 L111 L112 L113 L114 L115 L116 L117$ L118* L1190 L1205 L121: L122A L123G L124N L125U L126\ L127b L128i L129o L130u L131{ L132~ L133 L134 L135 L136 L137 L138 L139 L140 L141 L142 L143 L144 L145 L146 L147 L148 L149 L150 L151 L152 L153 L154 L155 L156 L157 L158 L159 L160 L161 L162 L163 L164 _regname# L165 L166 L167 L168 L169 L170 L171# L172& _type _space _incp _printin"L10007 L187@L189NL181L183L185L194L178L209L196L191^L180L186:~printininsfpwidspbyteindirL174L20005_prints _printc L184) _paddr"DL20006L200074_doubl"L192- L1931 L20008_branch"L1953 L1977 _printf L198P_inkdot _chkget L199= L200$L2016L203\L205@ L206C _psymoff L210D ~doublabL212J L213N ~branchinssL215L216P L10016 L10017 L10018 L10019" L10020* L217RL230zL233L240L234L236L231L237L239~paddrDarsaaL218VL219L220L221L20013L224LL223Q L10008L10011<L227R L10015rL232S L20015L235X L238^ L241L242L243d L10012L10013L244e L215L216P L10016 L10017#define STRUCT struct #define CHAR char #define BOOL char #define REG register #define INT int #define REAL double #define UNSIGNED unsigned #define STRING char * #define PTR int * #define EXITSW break #define BEGIN { #define END } #define IF if( #define THEN ){ #define ELSE } else { #define ELIF } else if ( #define FI } #define EXITFOR break #define FOR for( #define WHILE while( #define DO ){ #define OD } #define REP do{ #define PER }while( #define DONE ); #define LOOP for(;;){ #define POOL } #define SKIP ; #define DIV / #define REM % #define NEQ ^ #define ANDF && #define ORF || #define TRUE (-1) #define FALSE 0 #define LOBYTE 0377 #define HIBYTE 0177400 #define STRIP 0177 #define HEXMSK 017 #define SP ' ' #define TB '\t' #define NL '\n' #define EOF 0 #define maxint 32767 else { #define ELIF } else if ( #define FI } #define EXITFOR break #define FOR for( #define WHILE while( #define DO ){ #define OD } #define REP do{ #define PER }while( #define DONE ); #define LOOP for(;;){ #define POOL } #define # /* * * UNIX debugger - common definitions * */ /* Layout of a.out file (fsym): * * header of 8 words magic number 405, 407, 410, 411 * text size ) * data size ) in bytes but even * bss size ) * symbol table size * entry point * {unused} * flag set if no relocation * * * header: 0 * text: 16 * data: 16+textsize * relocation: 16+textsize+datasize * symbol table: 16+2*(textsize+datasize) or 16+textsize+datasize * */ #include "../head/param.h" #include "../head/user.h" #include "a68defs" #define DEVMEM "/dev/mem" #define DEVSWAP "/dev/swap" #define VARB 11 #define VARD 13 #define VARE 14 #define VARM 22 #define VARS 28 #define VART 29 #define MAXCOM 64 #define MAXARG 32 #define LINSIZ 256 #define TXTHDR 16 #define CORHDR 1024 #define COREMAGIC 0140000 #define RD 0 #define WT 1 #define NSP 0 #define ISP 1 #define DSP 2 #define STAR 4 #define STARCOM 0200 #define DSYM 7 #define ISYM 2 #define ASYM 1 #define NSYM 0 #define ESYM (-1) #define BKPTSET 1 #define BKPTEXEC 2 #define SYMSIZ 100 #define MAXSIG 20 #define USERPS 2*(512-1) #define USERPC 2*(512-2) #define UPROCP (&(0->u_procp)) #define BPT 03 #define TBIT 020 #define FD 0200 #define SETTRC 0 #define RDUSER 2 #define RIUSER 1 #define WDUSER 5 #define WIUSER 4 #define RUREGS 3 #define WUREGS 6 #define CONTIN 7 #define EXIT 8 #define ps -1 #define pc -2 #define sp -6 #define r5 -9 #define r4 -10 #define r3 -11 #define r2 -12 #define r1 -5 #define r0 -3 #define MAXOFF 255 #define MAXPOS 80 #define MAXLIN 128 #define EOF 0 #define EOR '\n' #define SP ' ' #define TB '\t' #define QUOTE 0200 #define STRIP 0177 #define LOBYTE 0377 #define EVEN -2 #define BADMOD 1 #define BADFMT 1 #define BADCOM 2 #define BADSYM 3 #define NOCRTN 4 #define NOMATCH 5 #define NOBKPT 6 #define BADKET 7 #define NOADR 8 #define NOPCS 9 #define BADVAR 10 #define BADTXT 11 #define BADDAT 12 #define ODDADR 13 #define EXBKPT 14 #define A68FRAME 15 #define A68LINK 16 #define ADRWRAP 17 #define BADEQ 18 #define BADWAIT 19 #define ENDPCS 20 #define NOFORK 21 #define BADSYN 22 #define NOEOR 23 #define LENBKPT 24 #define BADFIL 25 #define BADNAM 26 #define LONGFIL 27 #define NOTOPEN 28 /* long to ints and back (puns) */ struct { int hiword; int loword; }; struct { long longwd; }; struct { float realwd; }; int int2ws[2]; int lengws[2]; long longws[1]; float realws[1]; #define leng(a) (lengws[1]= a, lengws[0].longwd) #define shorten(a) (longws[0]= a, longws[0].loword) #define itol(a,b) (int2ws[0]= a, int2ws[1]= b, int2ws[0].longwd) #define ltor(a) (realws[0]= a, realws[0].longwd) /* file address maps */ #define MAP struct map MAP { long b1; long e1; long f1; long b2; long e2; long f2; int ufd; }; MAP txtmap; MAP datmap; #define SYMTAB struct symtab SYMTAB { char symc[8]; int symf; int symv; } symbol; BOOL localok; INT lastframe; INT callpc; #define SYMSLAVE struct symslave SYMSLAVE { INT valslave; INT typslave; }; SYMSLAVE *symvec; INT mkfault; INT executing; CHAR line[LINSIZ]; INT infile; INT outfile; CHAR *lp; INT maxoff; INT maxpos; INT sigint; INT sigqit; INT octal; ile address maps */ #define MAP struct map MAP { long b1; long e1; long f1; long b2; long e2; long f2; int ufd; }; MAP txtmap; MAP datmap; #define SYMTAB struct symtab SYMTAB { char symc[8]; int symf; int symv; } symbol; BOOL localok; INT lastframe; INT callpc; #define SYMSLAVE struct symslave SYMSLAVE { INT valslave; INT typslave; }; SYMSLAVE *symvec; INT mkfault; INT executing; CHAR line[LINSIZ]; INT infile; INT outfile; CHAR *lp; INT max# /* * * UNIX debugger - part 1 * */ #include "adb.h" int wtflag; int fcor; int fsym; long maxfile; long maxstor; long txtsiz; long datsiz; long stksiz; INT outfile 1; int errflg; int exitflg; int magic; long symbas; long symnum; long localval; int entrypt; char isymbol[8]; int signo; char lastc EOR; INT eof; char eqformat[128] "o"; char stformat[128] "o\"= \"^i"; int regbuf[512]; int *uregs; long dot; long ditto; int dotinc; int lastcom '='; long var[36]; long locval; long locmsk; char *symfil "a.out"; char *corfil "core"; int pid; long expv; long adrval; int adrflg; long cntval; int cntflg; char printbuf[]; char *printptr; char * errmsg[] { "", "bad modifier", "bad command", "symbol not found", "c routine not found", "cannot locate value", "no breakpoint set", "unexpected ')'", "address expected", "no process", "bad variable", "text address not found", "data address not found", "odd address", "too many breakpoints", "bad a68 frame", "bad a68 link", "address wrap around", "unexpected `='", "wait error: process disappeared!", "process terminated", "try again", "syntax error", "newline expected", "bkpt: command too long", "bad file format", "not enough space for symbols", "filename too long", "cannot open", }; long round(a,b) long a; long b; { long w; w = (a/b)*b; IF a>0 THEN w =+ b; FI return(w); } /* error handling */ error(n) { errflg=n; iclose(); oclose(); reset(); } fault(a) { signal(a,fault); printptr=printbuf; seek(infile,0,2); mkfault++; } /* set up files and initial address mappings */ int argcount; int devmem, devswap; main(argc, argv) char **argv; int argc; { maxfile=1; maxfile =<< 24; maxstor=1; maxstor =<< 16; WHILE argc>1 DO IF eqstr("-w",argv[1]) THEN wtflag=2; argc--; argv++; ELSE break; FI OD IF argc>1 THEN symfil = argv[1]; FI IF argc>2 THEN corfil = argv[2]; FI argcount=argc; setsym(); setcor(); setproc(); /* set up variables for user */ maxoff=MAXOFF; maxpos=MAXPOS; var[VARB] = datmap.b1; var[VARD] = datsiz; var[VARE] = leng(entrypt); var[VARM] = magic; var[VARS] = stksiz; var[VART] = txtsiz; IF (sigint=signal(SIGINT,fault))==01 THEN signal(SIGINT,1); ELSE sigint=fault; FI sigqit=signal(SIGQIT,1); setexit(); IF executing THEN delbp(); FI executing=FALSE; LOOP flushbuf(); IF errflg THEN printf("%s\n",errmsg[errflg]); exitflg=errflg; errflg=0; ELIF mkfault THEN mkfault=0; prints("\nadb\n"); FI lp=0; rdc(); lp--; IF eof THEN IF infile THEN iclose(); eof=0; reset(); ELSE done(); FI ELSE exitflg=0; FI command(0,lastcom); IF lp ANDF lastc!=EOR THEN error(NOEOR); FI POOL } done() { endpcs(); exit(exitflg); } setsym() { int relflg; INT symval, symflg; SYMSLAVE *symptr; SYMTAB *symp; IF !eqstr("-",symfil) THEN fsym=open(symfil,wtflag); IF wtflag ANDF fsym<0 THEN fsym=create(symfil); FI IF fsym<0 ANDF argcount>1 THEN printf("cannot open `%s'\n", symfil); FI ELSE fsym = -1; FI txtmap.ufd=fsym; IF read(fsym, regbuf, TXTHDR)==TXTHDR THEN magic=regbuf[0]; IF magic!=0411 ANDF magic!=0410 ANDF magic!=0407 ANDF magic!=0405 THEN magic=0; ELSE symnum=leng(regbuf[4])/12; txtsiz=leng(regbuf[1]); datsiz=leng(regbuf[2]); symbas=txtsiz+datsiz; txtmap.b1=0; txtmap.e1=(magic==0407?symbas:txtsiz); txtmap.f1 = TXTHDR; txtmap.b2=(magic==0410?round(txtsiz,leng(8192)):0); txtmap.e2=txtmap.b2+(magic==0407?symbas:datsiz); txtmap.f2 = TXTHDR+(magic==0407?0:txtmap.e1); entrypt=regbuf[5]; relflg=regbuf[7]; IF relflg!=1 THEN symbas =<< 1; FI symbas =+ TXTHDR; /* set up symvec */ freecell(symvec); symvec=getcell(shorten((1+symnum))*sizeof *symptr); IF (symptr=symvec)==0 THEN error(BADNAM); FI symset(); WHILE (symp=symget()) ANDF errflg==0 DO symval=symp->symv; symflg=symp->symf; symptr->valslave=symval; symptr->typslave=((symflg&070)==(symflg&040) ? ((symflg&07)>=3 ? DSYM : (symflg&07)) : NSYM ); symptr++; OD symptr->typslave=ESYM; FI FI IF magic==0 THEN txtmap.e1=maxfile; FI } setcor() { IF !eqstr("-",corfil) THEN fcor=open(corfil,wtflag); IF fcor<0 ANDF wtflag THEN fcor=create(corfil); FI IF fcor<0 ANDF argcount>2 THEN printf("cannot open `%s'\n", corfil); FI ELSE fcor = -1; FI datmap.ufd=fcor; IF read(fcor, regbuf, CORHDR)==CORHDR ANDF (regbuf[0]&0170000)==COREMAGIC ANDF (regbuf[1]&0170000)==COREMAGIC THEN signo = regbuf[0].u_arg[0]&017; txtsiz = leng(regbuf->u_tsize << 6); datsiz = leng(regbuf->u_dsize << 6); stksiz = leng(regbuf->u_ssize << 6); datmap.b1=(magic==0410?round(txtsiz,leng(8192)):0); datmap.e1=(magic==0407?txtsiz:datmap.b1)+datsiz; datmap.f1 = CORHDR; datmap.b2 = maxstor-stksiz; datmap.e2 = maxstor; datmap.f2 = CORHDR+(magic==0410?datsiz:datmap.e1); ELSE datmap.e1 = maxfile; FI } create(f) char *f; { int fd; IF (fd=creat(f,0644))>=0 THEN close(fd); return(open(f,wtflag)); ELSE return(-1); FI } /* input routines */ eol(c) char c; { return(c==EOR ORF c==';'); } rdc() { REP readchar(); PER lastc==SP ORF lastc==TB DONE return(lastc); } readchar() { IF eof THEN lastc=EOF; ELSE IF lp==0 THEN lp=line; REP eof = read(infile,lp,1)==0; IF mkfault THEN error(0); FI PER eof==0 ANDF *lp++!=EOR DONE *lp=0; lp=line; FI IF lastc = *lp THEN lp++; FI FI return(lastc); } nextchar() { IF eol(rdc()) THEN lp--; return(0); ELSE return(lastc); FI } quotchar() { IF readchar()=='\\' THEN return(readchar()); ELIF lastc=='\'' THEN return(0); ELSE return(lastc); FI } getformat(deformat) { register char *fptr, quote; fptr=deformat; quote=FALSE; WHILE (quote ? readchar()!=EOR : !eol(readchar())) DO IF (*fptr++ = lastc)=='"' THEN quote = ~quote; FI OD lp--; IF fptr!=deformat THEN *fptr++ = '\0'; FI } /* command decoding */ long inkdot(incr) { long newdot; newdot=dot+incr; IF (dot NEQ newdot) >> 24 THEN error(ADRWRAP); FI return(newdot); } long dekdot(decr) { long newdot; newdot=dot-decr; IF (dot NEQ newdot) >> 24 THEN error(ADRWRAP); FI return(newdot); } endline() { IF charpos()>=maxpos THEN printf("\n"); FI } command(buf,defcom) char *buf, defcom; { INT itype, ptype, modifier, regptr; INT fcount; BOOL longpr, eqcom; char wformat[1]; CHAR savc; long *amap, *smap, w, savdot; char *savlp; savlp=lp; IF buf THEN IF *buf==EOR THEN return(FALSE); ELSE lp=buf; FI FI REP IF adrflg=expr(0) THEN dot=expv; ditto=dot; FI adrval=dot; IF rdc()==',' ANDF expr(0) THEN cntflg=TRUE; cntval=expv; ELSE cntflg=FALSE; cntval=1; lp--; FI IF !eol(rdc()) THEN lastcom=lastc; ELSE IF adrflg==0 THEN dot=inkdot(dotinc); FI lp--; lastcom=defcom; FI switch(lastcom&STRIP) { case '/': itype=DSP; ptype=DSYM; goto trystar; case '=': itype=NSP; ptype=ASYM; goto trypr; case '?': itype=ISP; ptype=ISYM; goto trystar; trystar: IF rdc()=='*' THEN lastcom =| QUOTE; ELSE lp--; FI IF lastcom"E THEN itype =| STAR; ptype = (DSYM+ISYM)-ptype; FI trypr: longpr=FALSE; eqcom=lastcom=='='; switch (rdc()) { case 'm': {/*reset map data*/ IF eqcom THEN error(BADEQ); FI amap=(itype&DSP?&datmap:&txtmap); smap=amap; fcount=3; IF itype&STAR THEN amap =+ 3; FI WHILE fcount-- ANDF expr(0) DO *amap++ = expv; OD IF rdc()=='?' THEN smap->ufd=fsym; ELIF lastc == '/' THEN smap->ufd=fcor; ELSE lp--; FI printmap("new map",smap); } EXITSW; case 'L': longpr=TRUE; case 'l':  /*search for exp*/ IF eqcom THEN error(BADEQ); FI dotinc=2; savdot=dot; expr(1); locval=expv; IF expr(0) THEN locmsk=expv; ELSE locmsk = (longpr?-1:leng(-1)); FI LOOP w=leng(get(dot,itype)); IF longpr THEN w=itol(w,get(inkdot(2),itype)); FI IF errflg ORF (w&locmsk)==locval THEN break; FI dot=inkdot(dotinc); POOL IF errflg THEN dot=savdot; errflg=NOMATCH; FI psymoff(dot,ptype,""); EXITSW; case 'W':  longpr=TRUE; case 'w': IF eqcom THEN error(BADEQ); FI wformat[0]=lastc; expr(1); LOOP savdot=dot; psymoff(dot,ptype,":%16t"); exform(1,wformat,itype,ptype); errflg=0; dot=savdot; IF longpr THEN put(dot,itype,expv); FI put((longpr?inkdot(2):dot),itype,shorten(expv)); savdot=dot; printf("=%8t"); exform(1,wformat,itype,ptype); IF expr(0)==0 ORF errflg THEN break; FI POOL dot=savdot; EXITSW; default: lp--;  getformat(eqcom ? eqformat : stformat); IF !eqcom THEN psymoff(dot,ptype,":%16t"); FI scanform(cntval,(eqcom?eqformat:stformat),itype,ptype,1); } EXITSW; case '>': lastcom=0; savc=rdc(); IF regptr=getreg(savc) THEN uregs[regptr]=shorten(dot); ptrace(WUREGS,pid,2*(512+regptr),uregs[regptr]); ELIF (modifier=varchk(savc)) != -1 THEN var[modifier]=dot; ELSE error(BADVAR); FI EXITSW; case '!': lastcom=0; unix(); EXITSW; case '$': lastcom=0; printtrace(nextchar()); EXITSW; case ':': IF !executing THEN executing=TRUE; subpcs(nextchar()); executing=FALSE; lastcom=0; FI EXITSW; case 0: prints("adb"); EXITSW; default: error(BADCOM); } flushbuf(); PER rdc()==';' DONE IF buf THEN lp=savlp; ELSE lp--; FI return(adrflg ANDF dot!=0); } scanform(icount,ifp,itype,ptype,init) long int icount; { CHAR *fp, modifier; INT fcount; long savdot; WHILE icount DO fp=ifp; IF init==0 ANDF findsym(shorten(dot),ptype)==0 ANDF maxoff THEN printf("\n%.8s:%16t",symbol.symc); FI savdot=dot; init=0; /*now loop over format*/ WHILE *fp ANDF errflg==0 DO IF digit(modifier = *fp) THEN fcount=0; WHILE digit(modifier = *fp++) DO fcount =* 10; fcount =+ modifier-'0'; OD fp--; ELSE fcount=1; FI IF *fp==0 THEN break; FI fp=exform(fcount,fp,itype,ptype); OD dotinc=dot-savdot; dot=savdot; IF errflg THEN IF icount<0 THEN errflg=0; break; ELSE error(errflg); FI FI IF --icount THEN dot=inkdot(dotinc); FI IF mkfault THEN error(0); FI OD } exform(fcount,ifp,itype,ptype) INT fcount; char *ifp; int itype, ptype; { /* execute single format item `fcount' times * sets `dotinc' and moves `dot' * returns address of next format item */ int w; long savdot, wx; char *fp; char c, modifier, longpr; double fw; struct{long sa; int sb, sc;}; WHILE fcount>0 DO fp = ifp; c = *fp; longpr=(c>='A')&(c<='Z')|(c=='f'); IF itype==NSP ORF *fp=='a' THEN wx=dot; w=shorten(dot); ELSE w=get(dot,itype); IF longpr THEN wx=itol(w,get(inkdot(2),itype)); ELSE wx=leng(w); FI FI IF c=='F' THEN fw.sb=get(inkdot(4),itype); fw.sc=get(inkdot(6),itype); FI IF errflg THEN return(fp); FI IF mkfault THEN error(0); FI var[0]=wx; modifier = *fp++; dotinc=(longpr?4:2);; IF charpos()==0 ANDF modifier!='a' THEN printf("%16m"); FI switch(modifier) {  case SP: case TB: EXITSW; case 't': case 'T': printf("%T",fcount); return(fp); case 'r': case 'R': printf("%M",fcount); return(fp); case 'a': psymoff(dot,ptype,":%16t"); dotinc=0; EXITSW; case 'p': psymoff(var[0],ptype,"%16t"); EXITSW; case 'u': printf("%-8u",w); EXITSW; case 'U': printf("%-16U",wx); EXITSW; case 'c': case 'C': IF modifier=='C' THEN printesc(w&LOBYTE); ELSE printc(w&LOBYTE); FI dotinc=1; EXITSW;  case 'b': case 'B': printf("%-8o", w&LOBYTE); dotinc=1; EXITSW; case 's': case 'S': savdot=dot; dotinc=1; WHILE (c=get(dot,itype)&LOBYTE) ANDF errflg==0 DO dot=inkdot(1); IF modifier == 'S' THEN printesc(c); ELSE printc(c); FI endline(); OD dotinc=dot-savdot+1; dot=savdot; EXITSW; case 'x': printf("%-8x",w); EXITSW; case 'X': printf("%-16X", wx); EXITSW; case 'Y': printf("%-24Y", wx); EXITSW; case 'q': printf("%-8q", w); EXITSW; case 'Q': printf("%-16Q", wx); EXITSW; case 'o': case 'w': printf("%-8o", w); EXITSW; case 'O': case 'W': printf("%-16O", wx); EXITSW; case 'i': case 'I': dotinc=printins(0,itype,w); printc(EOR); EXITSW; case 'd': printf("%-8d", w); EXITSW; case 'D': printf("%-16D", wx); EXITSW; case 'f': fw = 0; fw.sa = wx; printf("%-16.7f", fw); dotinc=4; EXITSW; case 'F': fw.sa = wx; printf("%-32.14F", fw); dotinc=8; EXITSW; case 'n': case 'N': printc('\n'); dotinc=0; EXITSW; case '"': dotinc=0; WHILE *fp != '"' ANDF *fp DO printc(*fp++); OD IF *fp THEN fp++; FI EXITSW; case '^': dot=dekdot(dotinc*fcount); return(fp); case '+': dot=inkdot(fcount); return(fp); case '-': dot=dekdot(fcount); return(fp); default: error(BADFMT); } dot=inkdot(dotinc); fcount--; endline(); OD return(fp); } unix() { int rc, status, unixpid; char *argp; argp=lp; WHILE lastc!=EOR DO rdc(); OD IF (unixpid=fork())==0 THEN signal(SIGINT,sigint); signal(SIGQIT,sigqit); close(devmem); close(devswap); *lp=0; execl("/bin/sh", "-sh", "-c", argp, 0); exit(16); ELIF unixpid == -1 THEN error(NOFORK); ELSE signal(SIGINT,1); WHILE (rc = wait(&status)) != unixpid ANDF rc != -1 DONE signal(SIGINT,sigint); prints("!"); lp--; FI } printesc(c) { c =& STRIP; IF c'~' ORF c=='@' THEN printf("@%c",(c=='@' ? '@' : c^0140)); ELSE printc(c); FI } /* expression reading */ expr(a) { /* term | term dyadic expr | */ int rc; long lhs; rdc(); lp--; rc=term(a); WHILE rc DO lhs = expv; switch (readchar()) { case '+': term(a|1); expv =+ lhs; EXITSW; case '-': term(a|1); expv = lhs - expv; EXITSW; case '#': term(a|1); expv = round(lhs,expv); EXITSW; case '*': term(a|1); expv =* lhs; EXITSW; case '%': term(a|1); expv = lhs/expv; EXITSW; case '&': term(a|1); expv =& lhs; EXITSW; case '|': term(a|1); expv =| lhs; EXITSW; case ')': IF (a&2)==0 THEN error(BADKET); FI default: lp--; return(rc); } OD return(rc); } term(a) { /* item | monadic item | (expr) | */ switch (readchar()) { case '*': term(a|1); expv=leng(chkget(expv,DSP)); return(1); case '@': term(a|1); expv=leng(chkget(expv,ISP)); return(1); case '-': term(a|1); expv = -expv; return(1); case '~': term(a|1); expv = ~expv; return(1); case '(': expr(2); IF *lp!=')' THEN error(BADSYN); ELSE lp++; return(1); FI default: lp--; return(item(a)); } } item(a) { /* name [ . local ] | number | . | ^ | symv); FI lp--; ELIF digit(lastc) ORF (hex=TRUE, lastc=='#' ANDF hexdigit(readchar())) THEN expv = 0; base = (lastc == '0' ORF octal ? 8 : (hex ? 16 : 10)); WHILE (hex ? hexdigit(lastc) : digit(lastc)) DO expv =* base; IF (d=convdig(lastc))>=base THEN error(BADSYN); FI expv =+ d; readchar(); OD IF lastc=='.' ANDF (base==10 ORF expv==0) ANDF !hex THEN real=expv; frpt=0; base=10; WHILE digit(readchar()) DO real =* base; frpt++; real =+ lastc-'0'; OD WHILE frpt-- DO real =/ base; OD expv=ltor(real); FI lp--; ELIF lastc=='.' THEN expv=dot; ELIF lastc=='"' THEN expv=ditto; ELIF lastc=='+' THEN expv=inkdot(dotinc); ELIF lastc=='^' THEN expv=dekdot(dotinc); ELIF lastc=='<' THEN savc=rdc(); IF regptr=getreg(savc) THEN expv=leng(uregs[regptr]); ELIF (base=varchk(savc)) != -1 THEN expv=var[base]; ELSE error(BADVAR); FI ELIF lastc=='\'' THEN d=4; expv=0; WHILE quotchar() DO IF d-- THEN IF d==1 THEN expv =<<16; FI expv =| ((d&1)?lastc:lastc<<8); ELSE error(BADSYN); FI OD ELIF a THEN error(NOADR); ELSE lp--; return(0); FI return(1); } /* service routines for expression reading */ readsym() { register char *p; p = isymbol; REP IF p < &isymbol[8] THEN *p++ = lastc; FI readchar(); PER symchar(1) DONE WHILE p < &isymbol[8] DO *p++ = 0; OD } lookupsym(symstr) char *symstr; { struct symtab *symp; symset(); WHILE symp=symget() DO IF eqstr(symp->symc, symstr) THEN return(symp); FI OD return(0); } hexdigit(c) CHAR c; { return((c>='0' ANDF c<='9') ORF (c>='a' ANDF c<='f')); } convdig(c) CHAR c; { IF digit(c) THEN return(c-'0'); ELIF hexdigit(c) THEN return(c-'a'+10); ELSE return(17); FI } digit(c) char c; {return(c>='0' ANDF c<='9');} letter(c) char c; {return(c>='a' ANDF c<='z' ORF c>='A' ANDF c<='Z');} symchar(dig) { IF lastc=='\\' THEN readchar(); return(TRUE); FI return( letter(lastc) ORF lastc=='_' ORF dig ANDF digit(lastc) ); } varchk(name) { IF digit(name) THEN return(name-'0'); FI IF letter(name) THEN return((name&037)-1+10); FI return(-1); } <='f')); } convdig(c) CHAR c; { IF digit(c) THEN return(c-'0'); ELIF hexdigit(c) THEN return(c-'a'+10); ELSE return(17); FI } digit(c) char c; {return(c>='0' ANDF c<='9');} letter(c) char c; {return(c>='a' ANDF c<='z' ORF c>='A' ANDF c<='Z');} symchar(dig) { IF lastc=='\\' THEN readchar(); return(TRUE); FI return( letter(lastc) ORF lastc=='_' ORF dig ANDF digit(lastc) ); } varchk(name) { IF digit(name) THEN return(name-'0'); FI IF lett# /* * * UNIX debugger part 2 * */ #include "../head/proc.h" #include "adb.h" INT outfile; INT infile; /* symbol management */ long symbas; long symcnt; long symnum; long localval; char symrqd -1; SYMTAB symbuf[SYMSIZ]; SYMTAB *symnxt; SYMTAB *symend; /* breakpoints */ #define BKPT struct bkpt BKPT { int loc; int ins; int count; int initcnt; int flag; char comm[MAXCOM]; BKPT *nxtbkpt; } *bkpthead; #define REGLIST struct reglist REGLIST { char *rname; int roffs; } reglist[] { "ps", ps, "pc", pc, "sp", sp, "r5", r5, "r4", r4, "r3", r3, "r2", r2, "r1", r1, "r0", r0, }; #define SFREGS struct sfregs SFREGS { int junk[2]; int fpsr; float sfr[6]; }; #define LFREGS struct lfregs LFREGS { int junk[2]; int fpsr; double lfr[6]; }; #define FROFF (&(0->fpsr)) #define FRLEN 25 #define FRMAX 6 INT frnames[] { 0, 3, 4, 5, 1, 2 }; INT fault(); long inkdot(); char lastc; INT regbuf[512]; INT *uregs ®buf[512]; INT fcor; INT fsym; INT errflg; INT errno; INT signo; int devswap -1; int swapblk; int proctab; int devmem -1; long dot; long var[36]; char *symfil; char *corfil; int wtflag; INT pid; long expv; long adrval; INT adrflg; long cntval; long loopcnt; INT cntflg; char *signals[] { "", "hangup", "interrupt", "quit", "illegal instruction", "trace/BPT", "IOT", "EMT", "floating exception", "killed", "bus error", "memory fault", "bad system call", "broken pipe", "alarm call", "terminated", }; /* general printing routines ($) */ printtrace(modif) { INT narg, i, stat, dynam, name, limit; CHAR file[64]; INT index; REG BKPT *bkptr; CHAR hi, lo; INT word; CHAR *comptr; long argp, frame, link; SYMTAB *symp; IF cntflg==0 THEN cntval = -1; FI switch (modif) { case '<': case '>': { index=0; IF rdc()==EOR THEN IF modif=='<' THEN iclose(); ELSE oclose(); FI ELSE REP file[index++]=lastc; IF index>=63 THEN error(LONGFIL); FI PER readchar()!=EOR DONE file[index]=0; IF modif=='<' THEN infile=open(file,0); IF infile<0 THEN infile=0; error(NOTOPEN); FI ELSE outfile=open(file,1); IF outfile<0 THEN outfile=creat(file,0644); ELSE seek(outfile,0,2); FI FI FI lp--; } break; case 'o': octal = TRUE; EXITSW; case 'd': octal = FALSE; EXITSW; case 'q': case 'Q': done(); case 'w': case 'W': maxpos=(adrflg?adrval:MAXPOS); EXITSW; case 's': case 'S': maxoff=(adrflg?adrval:MAXOFF); EXITSW; case 'v': case 'V': prints("variables\n"); FOR i=0;i<=35;i++ DO IF var[i] THEN printc((i<=9 ? '0' : 'a'-10) + i); printf(" = %Q\n",var[i]); FI OD EXITSW; case 'm': case 'M': printmap("text map",&txtmap); printmap("data map",&datmap); EXITSW; case 0: case '?': IF pid THEN printf("pcs id = %d\n",pid); ELSE prints("no process\n"); FI printf("%s",signals[signo]); flushbuf(); case 'r': case 'R': printregs(); return; case 'f': case 'F': printfregs(modif=='F'); return; case 'c': case 'C': frame=(adrflg?adrval:leng(uregs[r5]))&EVEN; lastframe=0; callpc=uregs[pc]; WHILE mkfault==0 ANDF errflg==0 ANDF cntval-- DO narg = findroutine(frame); printf("%.8s(", symbol.symc); argp = frame+4; IF --narg >= 0 THEN printf("%o", get(argp, DSP)); FI WHILE --narg >= 0 DO argp =+ 2; printf(",%o", get(argp, DSP)); OD prints(")\n"); IF modif=='C' THEN WHILE localsym(frame) DO word=get(localval,DSP); printf("%8t%.8s:%10t", symbol.symc); IF errflg THEN prints("?\n"); errflg=0; ELSE printf("%o\n",word); FI OD FI lastframe=frame; frame=leng(get(frame, DSP))&EVEN; IF frame==0 THEN break; FI OD EXITSW; /*print externals*/ case 'e': case 'E': symset(); WHILE (symp=symget()) ANDF errflg==0 ANDF mkfault==0 DO IF (symp->symf)==043 ORF (symp->symf)==044 THEN printf("%.8s:%12t%o\n", symp->symc, get(leng(symp->symv),DSP)); FI OD EXITSW; case 'a': case 'A': frame=(adrflg ? adrval : leng(uregs[r4])); WHILE errflg==0 ANDF cntval-- ANDF mkfault==0 DO stat=get(frame,DSP); dynam=get(frame+2,DSP); link=get(frame+4,DSP); IF modif=='A' THEN printf("%8O:%8t%-8o,%-8o,%-8o",frame,stat,dynam,link); FI IF stat==1 THEN break; FI IF errflg THEN error(A68FRAME); FI IF get(link-4,ISP)!=04767 THEN IF get(link-2,ISP)!=04775 THEN error(A68LINK); ELSE /*compute entry point of routine*/ prints(" ? "); FI ELSE printf("%8t"); valpr(name=shorten(link)+get(link-2,ISP),ISYM); name=get(leng(name-2),ISP); printf("%8t\""); limit=8; REP word=get(leng(name),DSP); name =+ 2; lo=word&LOBYTE; hi=(word>>8)&LOBYTE; printc(lo); printc(hi); PER lo ANDF hi ANDF limit-- DONE printc('"'); FI limit=4; i=6; printf("%24targs:%8t"); WHILE limit-- DO printf("%8t%o",get(frame+i,DSP)); i =+ 2; OD printc(EOR); frame=leng(dynam); OD errflg=0; flushbuf(); EXITSW; /*set default c frame*/ /*print breakpoints*/ case 'b': case 'B': printf("breakpoints\ncount%8tbkpt%24tcommand\n"); FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt DO IF bkptr->flag THEN printf("%-8.8d",bkptr->count); psymoff(leng(bkptr->loc),ISYM,"%24t"); comptr=bkptr->comm; WHILE *comptr DO printc(*comptr++); OD FI OD EXITSW; default: error(BADMOD); } } printmap(s,amap) char *s; MAP *amap; { int file; file=amap->ufd; printf("%s%12t`%s'\n",s,(file<0 ? "-" : (file==fcor ? corfil : symfil))); printf("b1 = %-16Q",amap->b1); printf("e1 = %-16Q",amap->e1); printf("f1 = %-16Q",amap->f1); printf("\nb2 = %-16Q",amap->b2); printf("e2 = %-16Q",amap->e2); printf("f2 = %-16Q",amap->f2); printc(EOR); } printfregs(longpr) { REG i; double f; printf("fpsr %o\n", regbuf[0].fpsr); FOR i=0; irname, v=uregs[p->roffs]); valpr(v,(p->roffs==pc?ISYM:DSYM)); printc(EOR); OD printpc(); } getreg(regnam) { REG struct reglist *p; REG char *regptr; char regnxt; regnxt=readchar(); FOR p=reglist; p<®list[9]; p++ DO regptr=p->rname; IF (regnam == *regptr++) ANDF (regnxt == *regptr) THEN return(p->roffs); FI OD lp--; return(0); } printpc() { dot=leng(uregs[pc]); psymoff(dot,ISYM,":%16t"); printins(0,ISP,chkget(dot,ISP));  printc(EOR); } /* sub process control */ subpcs(modif) { REG INT check; INT execsig; REG BKPT *bkptr; char *comptr; execsig=0; loopcnt=cntval; switch(modif) { /* delete breakpoint */ case 'd': case 'D': IF (bkptr=scanbkpt(shorten(dot))) THEN bkptr->flag=0; return; ELSE error(NOBKPT); FI /* set breakpoint */ case 'b': case 'B': IF (bkptr=scanbkpt(shorten(dot))) THEN bkptr->flag=0; FI FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt DO IF bkptr->flag == 0 THEN break; FI OD IF bkptr==0 THEN IF (bkptr=getcell(sizeof *bkptr)) == -1 THEN error(EXBKPT); ELSE bkptr->nxtbkpt=bkpthead; bkpthead=bkptr; FI FI bkptr->loc = dot; bkptr->initcnt = bkptr->count = cntval; bkptr->flag = BKPTSET; check=MAXCOM-1; comptr=bkptr->comm; rdc(); lp--; REP *comptr++ = readchar(); PER check-- ANDF lastc!=EOR DONE *comptr=0; lp--; IF check THEN return; ELSE error(LENBKPT); FI /* exit */ case 'k' :case 'K': IF pid THEN printf("%d: killed", pid); endpcs(); return; FI error(NOPCS); /* run program */ case 'r': case 'R': endpcs(); setup(); uregs[ps] =& ~TBIT; EXITSW; /* single step */ case 's': case 'S': IF pid THEN uregs[ps] =| TBIT; execsig=getsig(signo); ELSE setup(); loopcnt--; FI EXITSW; /* continue with optional signal */ case 'c': case 'C': case 0: IF pid==0 THEN error(NOPCS); FI uregs[ps] =& ~TBIT; execsig=getsig(signo); EXITSW; default: error(BADMOD); } IF loopcnt>0 ANDF runpcs(execsig) THEN printf("breakpoint%16t"); ELSE printf("stopped at%16t"); FI delbp(); printpc(); } /* service routines for sub process control */ getsig(sig) { return(expr(0) ? shorten(expv) : sig); } runpcs(execsig) { INT rc; REG BKPT *bkpt; IF adrflg THEN ptrace(WUREGS,pid,USERPC,shorten(dot)); FI ptrace(WUREGS,pid,USERPS,uregs[ps]); setbp(); printf("%s: running\n", symfil); WHILE (loopcnt--)>0 DO /*DEBUG printf("\ncontinue %d\n",execsig); */  ptrace(CONTIN,pid,0,execsig); bpwait(TRUE); readregs(); /*look for bkpt*/ bkpt=scanbkpt(uregs[pc]-2); IF bkpt THEN /*stopped at bkpt*/ ptrace(WUREGS,pid,USERPC,uregs[pc]=bkpt->loc); IF bkpt->flag==BKPTEXEC ORF (bkpt->flag=BKPTEXEC, command(bkpt->comm,':')) ORF --bkpt->count THEN execbkpt(bkpt); execsig=0; loopcnt++; ELSE bkpt->count=bkpt->initcnt; rc=1; FI ELSE rc=0; execsig=signo; FI OD return(rc); } endpcs() { REG BKPT *bkptr; IF pid THEN ptrace(EXIT,pid,0,0); pid=0; FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt DO IF bkptr->flag THEN bkptr->flag=BKPTSET; FI OD FI } setup() { close(fsym); fsym = -1; IF (pid = fork()) == 0 THEN ptrace(SETTRC,0,0,0); signal(SIGINT,sigint); signal(SIGQIT,sigqit); close(devmem); close(devswap); doexec(); exit(0); ELIF pid == -1 THEN error(NOFORK); ELSE bpwait(FALSE); readregs(); lp[0]=EOR; lp[1]=0; fsym=open(symfil,wtflag); IF errflg THEN printf("%s: cannot execute\n",symfil); endpcs(); reset(); ELSE proctab=ptrace(RUREGS,pid,UPROCP,0); FI FI } execbkpt(bkptr) BKPT *bkptr; { int saveps, bkptloc; /*DEBUG printf("exbkpt: %d\n",bkptr->count); */ bkptloc = bkptr->loc; IF ((saveps=gtrace(RUREGS, USERPS, 0))&TBIT)==0 THEN ptrace(WUREGS,pid,USERPS,saveps|TBIT); FI ptrace(WIUSER,pid,bkptloc,bkptr->ins); ptrace(CONTIN,pid,0,0); bpwait(TRUE); ptrace(WIUSER,pid,bkptloc,BPT); bkptr->flag=BKPTSET; IF (saveps&TBIT)==0 THEN ptrace(WUREGS,pid,USERPS,gtrace(RUREGS,USERPS,0)&~TBIT); FI } doexec() { char *argl[MAXARG]; char args[LINSIZ]; char *p, **ap, *filnam; ap=argl; p=args; *ap++=symfil; REP IF rdc()==EOR THEN break; FI *ap = p; WHILE lastc!=EOR ANDF lastc!=SP ANDF lastc!=TB DO *p++=lastc; readchar(); OD *p++=0; filnam = *ap+1; IF **ap=='<' THEN close(0); IF open(filnam,0)<0 THEN printf("%s: cannot open\n",filnam); exit(0); FI ELIF **ap=='>' THEN close(1); IF creat(filnam,0666)<0 THEN printf("%s: cannot create\n",filnam); exit(0); FI ELSE ap++; FI PER lastc!=EOR DONE *ap++=0; exect(symfil, argl); } scanbkpt(adr) { REG BKPT *bkptr; FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt DO IF bkptr->flag ANDF bkptr->loc==adr THEN break; FI OD return(bkptr); } delbp() { REG INT a; REG BKPT *bkptr; FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt DO IF bkptr->flag THEN a=bkptr->loc; ptrace(WIUSER,pid,a,bkptr->ins); FI OD } setbp() { REG INT a; REG BKPT *bkptr; FOR bkptr=bkpthead; bkptr; bkptr=bkptr->nxtbkpt DO IF bkptr->flag THEN a = bkptr->loc; bkptr->ins = ptrace(RIUSER, pid, a, 0); ptrace(WIUSER, pid, a, BPT); IF errno THEN prints("cannot set breakpoint: "); psymoff(leng(bkptr->loc),ISYM,"\n"); FI FI OD } bpwait(exflg) { REG INT w; INT stat; signal(SIGINT, 1); WHILE (w = wait(&stat))!=pid ANDF w != -1 DONE signal(SIGINT,sigint); IF w == -1 THEN pid=0; errflg=BADWAIT; ELIF (stat & 0177) != 0177 THEN IF signo = stat&0177 THEN printf("%s", signals[signo]); FI IF stat&0200 THEN prints(" - core dumped"); close(fcor); setcor(); FI pid=0; errflg=ENDPCS; ELSE signo = stat>>8; IF signo!=SIGTRC THEN printf("%s\n", signals[signo]); ELSE signo=0; FI FI IF exflg ANDF errflg THEN reset(); FI } readregs() { /*get REG values from pcs*/ REG i; FOR i=0; i<9; i++ DO uregs[reglist[i].roffs] = gtrace(RUREGS, 2*(512+reglist[i].roffs), 0); OD /* floating point */ FOR i=FROFF; i=0 ANDF devswap>=0 ANDF seek(devmem, proctab, 0) != -1 ANDF read(devmem, mproc, sizeof mproc)==sizeof mproc ANDF pid==mproc[0].p_pid ANDF (mproc[0].p_flag&SLOAD)==0 THEN swapblk = mproc[0].p_addr; return(TRUE); ELSE return(FALSE); FI } setproc() { devswap=open(DEVSWAP,0); devmem=open(DEVMEM,0); } put(adr,space,value) long adr; { access(WT,adr,space,value); } get(adr, space) long adr; { return(access(RD,adr,space,0)); } chkget(n, space) long n; { REG w; w = get(n, space); IF errflg THEN reset(); FI return(w); } access(mode,adr,space,value) long adr; { int w, w1, pmode, rd, file; rd = mode==RD; IF space == NSP THEN return(0); FI IF pid /* tracing on? */ THEN IF adr&01 ANDF !rd THEN error(ODDADR); FI pmode = (space&DSP?(rd?RDUSER:WDUSER):(rd?RIUSER:WIUSER)); w = gtrace(pmode, shorten(adr), value); IF adr&01 THEN w1 = gtrace(pmode, shorten(adr+1), value); w = (w>>8)&LOBYTE | (w1<<8); FI IF errno THEN errflg = (space&DSP ? BADDAT : BADTXT); FI return(w); FI w = 0; IF !chkmap(&adr,space) THEN return(0); FI file=(space&DSP?datmap.ufd:txtmap.ufd); IF longseek(file,adr)==0 ORF (rd ? read(file,&w,2)<1 : write(file,&value,2)<1) THEN errflg=(space&DSP?BADDAT:BADTXT); FI return(w); } chkmap(adr,space) long *adr; int space; { MAP *amap; amap=(space&DSP?&datmap:&txtmap); IF space&STAR ORF !within(*adr,amap->b1,amap->e1) THEN IF within(*adr,amap->b2,amap->e2) THEN *adr =+ (amap->f2)-(amap->b2); ELSE errflg=(space&DSP?BADDAT:BADTXT); return(0); FI ELSE *adr =+ (amap->f1)-(amap->b1); FI return(1); } within(adr,lbd,ubd) long adr, lbd, ubd; { return(adr>=lbd && adr>9; /*DEBUG printf("file %d seek page %d offset %d\n",f,page,offset); */ return(seek(f,page,3) != -1 ANDF seek(f,offset,1) != -1); } valpr(v,idsp) { int d; d = findsym(v,idsp); IF d < maxoff THEN printf("%.8s", symbol.symc); IF d THEN printf("+%o", d); FI FI } localsym(cframe) long cframe; { INT symflg; WHILE nextsym() ANDF localok ANDF symbol.symc[0]!='~' ANDF (symflg=symbol.symf)!=037 DO IF symflg>=2 ANDF symflg<=4 THEN localval=leng(symbol.symv); return(TRUE); ELIF symflg==1 THEN localval=leng(shorten(cframe)+symbol.symv); return(TRUE); ELIF symflg==20 ANDF lastframe THEN localval=leng(lastframe+2*symbol.symv-10); return(TRUE); FI OD return(FALSE); } psymoff(v,type,s) long v; int type; char *s; { int w; w = findsym(shorten(v),type); IF w >= maxoff THEN printf("%Q",v); ELSE printf("%.8s", symbol.symc); IF w THEN printf("+%o",w); FI FI printf(s); } findsym(svalue,type) INT svalue, type; { long diff, value, symval, offset; INT symtyp; REG SYMSLAVE *symptr; SYMSLAVE *symsav; value=leng(svalue); diff=maxoff; symsav=0; IF type!=NSYM ANDF (symptr=symvec) THEN WHILE diff ANDF (symtyp=symptr->typslave)!=ESYM DO IF symtyp==type THEN symval=leng(symptr->valslave); IF value-symval=symval THEN diff = value-symval; symsav=symptr; FI FI symptr++; OD IF symsav THEN offset=leng(symsav-symvec); symcnt=symnum-offset; longseek(fsym, symbas+offset*12); read(fsym,&symbol,12); FI FI return(diff); } nextsym() { IF (--symcnt)<0 THEN return(FALSE); ELSE return(longseek(fsym, symbas+(symnum-symcnt)*12)!=0 ANDF read(fsym,&symbol,12)==12); FI } /* sequential search through file */ symset() { symcnt = symnum; symnxt = symbuf; IF symrqd THEN longseek(fsym, symbas); symread(); symrqd=FALSE; ELSE longseek(fsym, symbas+sizeof symbuf); FI } symget() { REG INT rc; IF symnxt >= symend THEN rc=symread(); symrqd=TRUE; ELSE rc=TRUE; FI IF --symcnt>0 ANDF rc==0 THEN errflg=BADFIL; FI return( (symcnt>=0 && rc) ? symnxt++ : 0); } symread() { int symlen; IF (symlen=read(fsym,symbuf,sizeof symbuf))>=12 THEN symnxt = symbuf; symend = &symbuf[symlen/12]; return(TRUE); ELSE return(FALSE); FI } = symnum; symnxt = symbuf; IF symrqd THEN longseek(fsym# /* * * UNIX debugger part 3 * */ #include "adb.h" /* value and symbol printing */ eqstr(as1, as2) char *as1, *as2; { REG char *s1, *s2, *es1; s1 = as1; s2 = as2; es1 = s1+8; IF *s1=='~' ORF *s1=='_' THEN IF *s2 != *s1 THEN s1++; FI FI WHILE *s1++ == *s2 DO IF *s2++ == 0 ORF s1>=es1 THEN return(1); FI OD return(0); } length(s) char *s; { int n; n=0; WHILE *s++ DO n++; OD return(n); } char printbuf[MAXLIN]; char *printptr printbuf, *digitptr; printc(c) char c; { char d, *q; int posn, tabs, p; IF mkfault THEN return; ELIF (*printptr=c)==EOR THEN tabs=0; posn=0; q=printbuf; FOR p=0; p0 DO *q++=TB; tabs--; OD WHILE posn>0 DO *q++=SP; posn--; OD *q++=d; FI OD *q++=EOR; write(outfile,printbuf,q-printbuf); printptr=printbuf; ELIF c==TB THEN *printptr++=SP; WHILE (printptr-printbuf)&7 DO *printptr++=SP; OD ELIF c THEN printptr++; FI } charpos() { return(printptr-printbuf); } flushbuf() { IF printptr!=printbuf THEN printc(EOR); FI } printf(fmat,a1) char *fmat, **a1; { char *fptr, *s; int *vptr; long *dptr; double *rptr; int x, decpt, n; long lx; int width, prec; char c, adj; char digits[64]; fptr=fmat; vptr = &a1; WHILE c = *fptr++ DO IF c!='%' THEN printc(c); ELSE IF *fptr=='-' THEN adj='l'; fptr++; ELSE adj='r'; FI width=convert(&fptr); IF *fptr=='.' THEN fptr++; prec=convert(&fptr); ELSE prec = -1; FI digitptr=digits; dptr=rptr=vptr; lx = *dptr; x = *vptr++; s=0; switch (c = *fptr++) { case 'd': case 'u': printnum(x,c,10); break; case 'o': printoct(0,x,0); break; case 'q': lx=x; printoct(lx,-1); break; case 'x': printdbl(0,x,c,16); break; case 'Y': printdate(lx); vptr++; break; case 'D': case 'U': printdbl(lx,c,10); vptr++; break; case 'O': printoct(lx,0); vptr++; break; case 'Q': printoct(lx,-1); vptr++; break; case 'X': printdbl(lx,'x',16); vptr++; break; case 'c': printc(x); break; case 's': s=x; break; case 'f': case 'F': vptr =+ 7; s=ecvt(*rptr, prec, &decpt, &n); *digitptr++=(n?'-':'+'); *digitptr++ = (decpt<=0 ? '0' : *s++); IF decpt>0 THEN decpt--; FI *digitptr++ = '.'; WHILE *s ANDF prec-- DO *digitptr++ = *s++; OD WHILE *--digitptr=='0' DONE digitptr =+ (digitptr-digits>=3 ? 1 : 2); IF decpt THEN *digitptr++ = 'e'; lx=decpt; printoct(lx,-1); FI s=0; prec = -1; break; case 'm': vptr--; break; case 'M': width=x; break; case 'T': case 't': IF c=='T' THEN width=x; ELSE vptr--; FI IF width THEN width =- charpos()%width; FI break; default: printc(c); vptr--; } IF s==0 THEN *digitptr=0; s=digits; FI n=length(s); n=(prec=0 ? prec : n); width =- n; IF adj=='r' THEN WHILE width-- > 0 DO printc(SP); OD FI WHILE n-- DO printc(*s++); OD WHILE width-- > 0 DO printc(SP); OD digitptr=digits; FI OD } printdate(tvec) long tvec; { STRING timeptr; REG INT i; timeptr = ctime(&tvec); FOR i=20; i<24; i++ DO *digitptr++ = *(timeptr+i); OD FOR i=3; i<19; i++ DO *digitptr++ = *(timeptr+i); OD } /*printdate*/ prints(s) char *s; { printf("%s",s); } convert(cp) char **cp; { char c; int n; n=0; WHILE ((c = *(*cp)++)>='0') ANDF (c<='9') DO n=n*10+c-'0'; OD (*cp)--; return(n); } printnum(n,fmat,base) { char k; int digs[15]; int *dptr; extern int ldivr; dptr=digs; IF n<0 ANDF fmat=='d' THEN n = -n; *digitptr++ = '-'; FI WHILE n DO n=ldiv(0,n,base); *dptr++ = ldivr; OD IF dptr==digs THEN *dptr++=0; FI WHILE dptr!=digs DO k = *--dptr; *digitptr++ = (k+(k<=9 ? '0' : 'a'-10)); OD } printoct(o,s) long o; int s; { int i; long po; char digs[12]; po = o; IF s THEN IF po<0 THEN po = -po; *digitptr++='-'; ELSE IF s>0 THEN *digitptr++='+'; FI FI FI FOR i=0;i<=11;i++ DO digs[i] = po&7; po =>> 3; OD digs[10] =& 03; digs[11]=0; FOR i=11;i>=0;i-- DO IF digs[i] THEN EXITFOR; FI OD FOR i++;i>=0;i-- DO *digitptr++=digs[i]+'0'; OD } printdbl(lx,ly,fmat,base) INT lx, ly; char fmat; int base; { int digs[20]; int *dptr; char k; double f ,g; long q; dptr=digs; IF fmat!='D' THEN f=leng(lx); f =* itol(1,0); f =+ leng(ly); IF fmat=='x' THEN *digitptr++='#'; FI ELSE f=itol(lx,ly); IF f<0 THEN *digitptr++='-'; f = -f; FI FI WHILE f DO q=f/base; g=q;  *dptr++ = f-g*base; f=q; OD IF dptr==digs THEN *dptr++=0; FI WHILE dptr!=digs DO k = *--dptr; *digitptr++ = (k+(k<=9 ? '0' : 'a'-10)); OD } iclose() { IF infile THEN close(infile); infile=0; FI } oclose() { IF outfile!=1 THEN flushbuf(); close(outfile); outfile=1; FI } ; dptr=digs; IF fmat!='D' THEN f=leng(lx); f =* itol(1,0); f =+ leng(ly); IF fmat=='x' THEN *digitptr++='#'; FI ELSE f=itol(lx,ly); IF f<0 THEN *digitptr++='-'; f = -f; FI FI WHILE f DO q=f/base; g=q; # /* * * UNIX debugger part 4 * */ #include "adb.h" int errflg; long dot; long var[36]; long inkdot(); findroutine(cframe) long cframe; { int narg, inst, lastpc, back2; BOOL v; v=FALSE; localok=FALSE; lastpc=callpc; callpc=get(cframe+2, DSP); back2=get(leng(callpc-2), ISP); IF (inst=get(leng(callpc-4), ISP)) == 04737 /* jsr pc,*$... */ THEN narg = 1; ELIF (inst&~077)==04700 /* jsr pc,... */ THEN narg=0; v=(inst!=04767); ELIF (back2&~077)==04700 THEN narg=0; v=TRUE; ELSE errflg=NOCRTN; return(0); FI IF findsym( (v ? lastpc : ((inst==04767?callpc:0) + back2) ),ISYM) ANDF !v THEN symbol.symc[0] = '?'; symbol.symc[1] = 0; symbol.symv = 0; ELSE localok=TRUE; FI inst = get(leng(callpc), ISP); IF inst == 05726 /* tst (sp)+ */ THEN return(narg+1); FI IF inst == 022626 /* cmp (sp)+,(sp)+ */ THEN return(narg+2); FI IF inst == 062706 /* add $n,sp */ THEN return(narg+get(leng(callpc+2), ISP)/2); FI return(narg); } /* instruction printing */ #define DOUBLE 0 #define DOUBLW 1 #define SINGLE 2 #define SINGLW 3 #define REVERS 4 #define BRANCH 5 #define NOADDR 6 #define DFAULT 7 #define TRAP 8 #define SYS 9 #define SOB 10 #define JMP 11 #define JSR 12 #define OPTAB struct optab OPTAB { int mask; int val; int itype; char *iname; } optab[] { 0107777, 0010000, DOUBLE, "mov", 0107777, 0020000, DOUBLE, "cmp", 0107777, 0030000, DOUBLE, "bit", 0107777, 0040000, DOUBLE, "bic", 0107777, 0050000, DOUBLE, "bis", 0007777, 0060000, DOUBLE, "add", 0007777, 0160000, DOUBLE, "su", 0100077, 0005000, SINGLE, "clr", 0100077, 0005100, SINGLE, "com", 0100077, 0005200, SINGLE, "inc", 0100077, 0005300, SINGLE, "dec", 0100077, 0005400, SINGLE, "neg", 0100077, 0005500, SINGLE, "adc", 0100077, 0005600, SINGLE, "sbc", 0100077, 0005700, SINGLE, "tst", 0100077, 0006000, SINGLE, "ror", 0100077, 0006100, SINGLE, "rol", 0100077, 0006200, SINGLE, "asr", 0100077, 0006300, SINGLE, "asl", 0000077, 0000100, JMP, "jmp", 0000077, 0000300, SINGLE, "swab", 0000077, 0170100, SINGLW, "ldfps", 0000077, 0170200, SINGLW, "stfps", 0000077, 0170300, SINGLW, "stst", 0000077, 0170400, SINGLW, "clrf", 0000077, 0170500, SINGLW, "tstf", 0000077, 0170600, SINGLW, "absf", 0000077, 0170700, SINGLW, "negf", 0000077, 0006700, SINGLW, "sxt", 0000077, 0006600, SINGLW, "mtpi", 0000077, 0106600, SINGLW, "mtpd", 0000077, 0006500, SINGLW, "mfpi", 0000077, 0106500, SINGLW, "mfpd", 0000777, 0070000, REVERS, "mul", 0000777, 0071000, REVERS, "div", 0000777, 0072000, REVERS, "ash",  0000777, 0073000, REVERS, "ashc", LOBYTE, 0000400, BRANCH, "br", LOBYTE, 0001000, BRANCH, "bne", LOBYTE, 0001400, BRANCH, "beq", LOBYTE, 0002000, BRANCH, "bge", LOBYTE, 0002400, BRANCH, "blt", LOBYTE, 0003000, BRANCH, "bgt", LOBYTE, 0003400, BRANCH, "ble", LOBYTE, 0100000, BRANCH, "bpl", LOBYTE, 0100400, BRANCH, "bmi", LOBYTE, 0101000, BRANCH, "bhi", LOBYTE, 0101400, BRANCH, "blos", LOBYTE, 0102000, BRANCH, "bvc", LOBYTE, 0102400, BRANCH, "bvs", LOBYTE, 0103000, BRANCH, "bcc", LOBYTE, 0103400, BRANCH, "bcs", 0000000, 0000000, NOADDR, "halt", 0000000, 0000001, NOADDR, "wait", 0000000, 0000002, NOADDR, "rti", 0000000, 0000003, NOADDR, "bpt", 0000000, 0000004, NOADDR, "iot", 0000000, 0000005, NOADDR, "reset", LOBYTE, 0171000, REVERS, "mulf", LOBYTE, 0171400, REVERS, "modf", LOBYTE, 0172000, REVERS, "addf", LOBYTE, 0172400, REVERS, "movf", LOBYTE, 0173000, REVERS, "subf", LOBYTE, 0173400, REVERS, "cmpf", LOBYTE, 0174000, DOUBLW, "movf", LOBYTE, 0174400, REVERS, "divf", LOBYTE, 0175000, DOUBLW, "movei", LOBYTE, 0175400, DOUBLW, "movfi", LOBYTE, 0176000, DOUBLW, "movfo", LOBYTE, 0176400, REVERS, "movie", LOBYTE, 0177000, REVERS, "movif", LOBYTE, 0177400, REVERS, "movof", 0000000, 0170000, NOADDR, "cfcc", 0000000, 0170001, NOADDR, "setf", 0000000, 0170002, NOADDR, "seti", 0000000, 0170011, NOADDR, "setd", 0000000, 0170012, NOADDR, "setl", 0000777, 0004000, JSR, "jsr", 0000777, 0074000, DOUBLE, "xor", 0000007, 0000200, SINGLE, "rts", 0000017, 0000240, DFAULT, "cflg", 0000017, 0000260, DFAULT, "sflg", LOBYTE, 0104000, TRAP, "emt", LOBYTE, 0104400, SYS, "sys", 0000077, 0006400, TRAP, "mark", 0000777, 0077000, SOB, "sob", 0000007, 0000230, TRAP, "spl", 0177777, 0000000, DFAULT, "", }; #define SYSTAB struct systab SYSTAB { int argc; char *sname; } systab[] { 1, "indir", 0, "exit", 0, "fork", 2, "read", 2, "write", 2, "open", 0, "close", 0, "wait", 2, "creat", 2, "link", 1, "unlink", 2, "exec", 1, "chdir", 0, "time", 3, "mknod", 2, "chmod", 2, "chown", 1, "break", 2, "stat", 2, "seek", 0, "getpid", 3, "mount", 1, "umount", 0, "setuid", 0, "getuid", 0, "stime", 3, "ptrace", 0, "alarm", 1, "fstat", 0, "pause", 1, "30", 1, "stty", 1, "gtty", 0, "access", 0, "nice", 0, "sleep", 0, "sync", 1, "kill", 0, "csw", 0, "setpgrp", 0, "tell", 0, "dup", 0, "pipe", 1, "times", 4, "profil", 0, "tiu", 0, "setgid", 0, "getgid", 2, "signal", 0, "49", 0, "50", 0, "51", 0, "52", 0, "53", 0, "54", 0, "55", 0, "56", 0, "57", 0, "58", 0, "59", 0, "60", 0, "61", 0, "62", 0, "63", }; char *regname[] { "r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc"}; INT type, space, incp; printins(f,idsp,ins) { int indir, byte; register w; register OPTAB *p; type=DSYM; space=idsp; incp=2; FOR p=optab;; p++ DO IF (ins & ~p->mask) == p->val THEN break; FI OD prints(p->iname); byte=ins&0100000; ins =& p->mask; switch (p->itype) { case JMP: type=ISYM; case SINGLE: IF byte THEN printc('b'); FI case SINGLW: paddr("%8t",ins); EXITSW; case REVERS: doubl(ins&077,(ins>>6)&07); EXITSW; case JSR: type=ISYM; case DOUBLE: IF byte THEN printc('b'); FI case DOUBLW: doubl(ins>>6,ins); case NOADDR: EXITSW; case SOB: paddr("%8t",(ins>>6)&07); branch(",",-(ins&077)); EXITSW; case BRANCH: branch("%8t",ins); EXITSW; case SYS: printf("%8t%s", systab[ins =& 077].sname); IF ins==0 ANDF f==0 ANDF idsp!=NSP /* indir */ THEN w=dot; dot=leng(chkget(inkdot(2),idsp)); prints(" {"); indir=get(dot,DSP); IF errflg THEN errflg=0; printc('?'); ELSE printins(1,DSP,indir); FI printc('}'); dot=w; incp=4; ELSE w = systab[ins].argc; WHILE w-- ANDF idsp!=NSP DO prints("; "); psymoff(leng(get(inkdot(incp),idsp)), NSYM, ""); incp =+ 2; OD FI EXITSW; case TRAP: case DFAULT: default: printf("%8t%o", ins); } return(incp); } doubl(a,b) {  paddr("%8t",a); paddr(",",b); } branch(s,ins) char *s; int ins; { printf(s); IF ins&0200 THEN ins =| 0177400; FI ins = shorten(dot) + (ins<<1) + 2; psymoff(leng(ins),ISYM,""); } paddr(s,aa) char *s; int aa; { register a, r; var[2]=var[1]; a=aa; r=a&07; a =& 070; printf(s); IF r==7 ANDF a&020 THEN IF a&010 THEN printc('*'); FI IF a&040 THEN IF space==NSP THEN printc('?'); ELSE var[1]=leng( chkget(inkdot(incp),space) + shorten(inkdot(incp+2)) ); psymoff(var[1],(a&010?DSYM:type),""); FI ELSE printc('$'); IF space==NSP THEN printc('?'); ELSE var[1]=leng(chkget(inkdot(incp), space)); psymoff(var[1], (a&010?type:NSYM), ""); FI FI incp =+ 2; return; FI r = regname[r]; switch (a) { /* r */ case 000: prints(r); return; /* (r) */ case 010: printf("(%s)", r); return; /* *(r)+ */ case 030: printc('*'); /* (r)+ */ case 020: printf("(%s)+", r); return; /* *-(r) */ case 050: printc('*'); /* -(r) */ case 040: printf("-(%s)", r); return; /* *x(r) */ case 070: printc('*'); /* x(r) */ case 060: IF space==NSP THEN printc('?'); ELSE var[1]=leng(chkget(inkdot(incp), space)); psymoff(var[1], (a==070?type:NSYM), ""); FI incp =+ 2; printf("(%s)", r); return; } } ntf("(%s)", r); return; /* *(r)+ */ case 030: printc('*'); /* (r)+ */ case 020: printf("(%s)+", r); return; /* *-(r) */ cas# ifdef unix # define cfree free calloc(m,n) { int storep; storep = alloc(m*n); if (storep == -1) {write(2, "memory space exceeded\n",22); exit();} return(storep); } # endif aabalance(ru,s,len,ex) char *s; { struct node *p, *op, **pp, *r, *st; char *cp; pp = &(aaroot[ru]); while (*pp) { p = *pp; switch (aacomp(s, p->aakey)) { case '>': pp= &(p->rp); break; case '<': pp= &(p->lp); break; case '=': if (ex >= 0) return(p->aadata); cfree (p->aadata, len, 1); cfree(p->aakey, aaclen(p->aakey), 1); if (p->rp == 0) *pp = p->lp; else { r = p->rp; if (r->lp == 0) { r->lp = p->lp; *pp = r; } else { st = r->lp; while (st->lp != 0) { r = st; st = r->lp; } st->lp = p->lp; r->lp = st->rp; st->rp = p->rp; *pp = st; } } cfree (p, sizeof(**aaroot), 1); return(0); } op=p; } /* not there */ if (ex != 0) return(0); p = *pp= calloc(1, sizeof(**aaroot)); p->aakey = calloc(aaclen(s),1); cp = p->aakey; while (*cp++ = *s++); p->aadata = calloc(len,1); cp = p->aadata; while (len--) *cp++ = 0; p->rp = p->lp = 0; return(p->aadata); } aaclen(s) char *s; { int aak; for(aak=1; *s++; aak++); return(aak); } aacomp(s,t) char *s, *t; { int c,d; while ( (c= *s++) == (d= *t++) ) if (c== 0) return('='); return(c>d ? '>' : '<'); } btod(n, s) char *s; { int digs[15], *dpt; dpt = digs; if (n >= 0) n = -n; else *s++ = '-'; for (; n != 0; n = n/10) *dpt++ = n%10; if (dpt == digs) *dpt++ = 0; while (dpt != digs) *s++ = '0' - *--dpt; *s++ = '|'; return(s); } p = p->aadata; while (len--) *cp++ = 0; p->rp = p->lp = 0; return(p->aadata); } aaclen(s) char *s; { int aak; for(aak=1; *s++; aak++); return(aak); } aacomp(s,t) char *s, *t; { int c,d; while ( (c= *s++) == (d= *t++) ) if (c== 0) return('='); return(c>d ? '>' : '<'); } btod(n, s) char *s; { int digs[15], *dpt; dpt = digs; if (n >= 0) n = -n; else *s++ = '-'; for (; n != 0; n = n/10) *dpt++ = n%10; if (dpt == digs) *dpt++ = 0; while (dpt != digaabinary(ru,vi,li,s,len,ex) char *s; int *vi; { struct node *p, *op, *r, *st, **pp, *gr; char *cp; int *xp; gr = 0; pp = &(aaroot[ru]); while (*pp) { p = *pp; switch(aacomp(p->aakey, vi, li, s)) { case '<': small: pp= &(p->rp); break; case '>': pp= &(p->lp); gr = p; break; case '=': if (ex == 2) goto small; if (ex >= 0) return(p->aadata); cfree (p->aadata, len, 1); cfree(p->aakey, aaclen(p->aakey)+ li*sizeof(li), 1); if (p->rp == 0) *pp = p->lp;  else { r = p->rp; if (r->lp == 0) { r->lp = p->lp; *pp = r; } else { st = r->lp; while (st->lp != 0) { r = st; st = r->lp; } st->lp = p->lp; r->lp = st->rp; st->rp = p->rp; *pp = st; } } cfree (p, sizeof(**aaroot), 1); return(0); } op=p; } /* not there */ if (ex==2) return (gr ? gr->aakey : 0); if (ex != 0) return(0); p = *pp= calloc(1, sizeof(**aaroot)); p->aakey = calloc(aaclen(s)+li*sizeof(li),1); xp = p->aakey; while (li--) *xp++ = *vi++; cp=xp; while (*cp++ = *s++); p->aadata = calloc(len,1); cp = p->aadata; while (len--) *cp++ = 0; p->rp = p->lp = 0; return(p->aadata); } st = r->lp; } st->lp = p->lp; r->lp = st->rp; st->rp = p->rp; *pp = st; } } cfree (p, sizeof(**aaroot), 1); return(0); } op=p; } /* not there */ if (ex==2) return (gr ? gr->aakey : 0); if (ex != 0) return(0); p = *pp= calloc(1, sizeof(**aaroot)); p->aakey = calloc(aaclen(s)+li*sizeof(li),1); xp = p->aakey; while (li-int aatsize, aapr1, aapr2; aahash(tbl,vi,li,s,len,ex) char *s; int *vi; struct hnode tbl[]; { struct hnode *p, *op, *r, *st; char *cp; int i, key, c, p1, p2, q1, *v, l, *ip, k; cp = s; key =0; v = vi; l = li; while (l--) key = key + (key<<5) + *v++; while (c = *cp++) key = key + (key<<5) + c; key =& 077777; q1 = 0; p1 = key%aapr1; p2 = key%aapr2; if (p2==0) p2=17; for(i=0; i 0 ; li--) *ip++ = *v++; for(cp=ip; *cp++ = *s++;); cp = tbl[p1].aadata = calloc(len,1); while (len--) *cp++ = 0; return(tbl[p1].aadata); } else if (ex == 2) { for (p1=0; p1 d ? '>' : '<'); s= p; while ( (c= *s++) == (d= *t++) ) if (c== 0) return('='); return(c>d ? '>' : '<'); } s)== '=') { if (ex == 2) { # #define YYLMAX 200 # define BINARY 1 # define HASH 2 int yylexl(); extern int yyleng; extern char yytext[]; extern struct {int *yyaa, *yybb, *yycc;} yysvec[], *yybgin; int (*yyplex)() &yylexl; yylex() { return( (*yyplex)() ); } # define REJECT {nstr=yyreject(); goto fussy;} # define ECHO printf("%s", yytext); yylexl() { int nstr; char s[200]; while((nstr=yylook()) >= 0) fussy: switch(nstr) { case 0: if (yywrap()) return(0); break; case 1: return(Int);break; case 2: return(Char);break; case 3: return(String);break; case 4: return(Size);break; case 5: return(Exist);break; case 6: { yylval = HASH; return(Method); }break; case 7: { yylval = BINARY; return(Method); }break; case 8: { while (gets(s) && !streq(s,"%}")) puts(s); }break; case 9: return(0);break; case 10: ;break; case 11: { return(name); }break; case 12: { scanf (-1, yytext, "%d", &yylval); return(number); }break; case 13: return('(');break; case 14: return(')');break; case 15: return(yytext[0]);break;;} } streq(s,t) char *s, *t; { int c; while ((c= *s++) == *t++) if (c==0) return(1); return(0); } # define YYNEWLINE 10 struct yywork {int *verify, *advance;} yycrank[] { 0, 0, 0, 0, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+12, yysvec+1, yysvec+13, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+12, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+14, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+15, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+17, yysvec+1, yysvec+11, yysvec+1, yysvec+18, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+16, yysvec+1, yysvec+19, yysvec+1, yysvec+20, yysvec+1, yysvec+16, yysvec+1, yysvec+21, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+22, yysvec+1, yysvec+23, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+24, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+16, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+1, yysvec+11, yysvec+3, yysvec+4, yysvec+5, yysvec+6, yysvec+6, yysvec+7, yysvec+7, yysvec+8, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+19, yysvec+25, yysvec+20, yysvec+26, yysvec+21, yysvec+27, yysvec+22, yysvec+28, yysvec+23, yysvec+29, yysvec+25, yysvec+32, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+9, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+10, yysvec+24, yysvec+30, yysvec+26, yysvec+33, yysvec+27, yysvec+34, yysvec+28, yysvec+35, yysvec+29, yysvec+36, yysvec+30, yysvec+37, yysvec+31, yysvec+38, yysvec+32, yysvec+39, yysvec+33, yysvec+40, yysvec+34, yysvec+41, yysvec+35, yysvec+42, yysvec+24, yysvec+31, yysvec+37, yysvec+43, yysvec+38, yysvec+44, yysvec+39, yysvec+45, yysvec+41, yysvec+46, yysvec+44, yysvec+47, yysvec+45, yysvec+48, yysvec+47, yysvec+49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int yyvstop[] { 0, 8, 0, 9, 0, 11, 0, 12, 0, 15, 0, 10, 15, 0, 10, 0, 12, 15, 0, 11, 15, 0, 13, 15, 0, 14, 15, 0, 1, 11, 0, 2, 11, 0, 6, 11, 0, 4, 11, 0, 5, 11, 0, 7, 11, 0, 3, 11, 0, 0}; struct yysvf { struct yywork *yystoff; struct yysvf *yyother; int *yystops;} yysvec []{ 0,0,0, yycrank+1, 0,0, yycrank+0, yysvec+1,0, yycrank+6, 0,0, 0, 0,yyvstop+1, yycrank+93, 0,0, yycrank+94, 0,0, yycrank+122, 0,0, 0, 0,yyvstop+3, yycrank+68, 0,yyvstop+5, yycrank+143, 0,yyvstop+7, 0, 0,yyvstop+9, 0, 0,yyvstop+11, 0, yysvec+5,yyvstop+14, 0, yysvec+3,yyvstop+9, 0, yysvec+10,yyvstop+16, 0, yysvec+9,yyvstop+19, 0, 0,yyvstop+22, 0, 0,yyvstop+25, yycrank+54, yysvec+9,yyvstop+19, yycrank+56, yysvec+9,yyvstop+19, yycrank+41, yysvec+9,yyvstop+19, yycrank+65, yysvec+9,yyvstop+19, yycrank+53, yysvec+9,yyvstop+19, yycrank+96, yysvec+9,yyvstop+19, yycrank+54, yysvec+9,yyvstop+5, yycrank+105, yysvec+9,yyvstop+5, yycrank+98, yysvec+9,yyvstop+5, yycrank+89, yysvec+9,yyvstop+5, yycrank+89, yysvec+9,yyvstop+5, yycrank+84, yysvec+9,yyvstop+5, yycrank+93, yysvec+9,yyvstop+5, yycrank+111, yysvec+9,yyvstop+5, yycrank+95, yysvec+9,yyvstop+5, yycrank+95, yysvec+9,yyvstop+5, yycrank+107, yysvec+9,yyvstop+5, 0, yysvec+9,yyvstop+28, yycrank+112, yysvec+9,yyvstop+5, yycrank+109, yysvec+9,yyvstop+5, yycrank+101, yysvec+9,yyvstop+5, 0, yysvec+9,yyvstop+31, yycrank+100, yysvec+9,yyvstop+5, 0, yysvec+9,yyvstop+34, 0, yysvec+9,yyvstop+37, yycrank+107, yysvec+9,yyvstop+5, yycrank+97, yysvec+9,yyvstop+5, 0, yysvec+9,yyvstop+40, yycrank+116, yysvec+9,yyvstop+5, 0, yysvec+9,yyvstop+43, 0, yysvec+9,yyvstop+46, 0,0,0}; int yyextra[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; struct yysvf *yylstate [YYLMAX], **yylsp, **yyolsp; int *yyfnd, yymorfg, yyleng; char yytext[YYLMAX]; struct yysvf *yybgin yysvec+1; int yyprevious YYNEWLINE; yylook () { register struct yysvf *state, **lsp; register struct yywork *r; int ch, n; char *yylastch; /* start off machines */ if (!yymorfg) yylastch = yytext; else { yymorfg=0; yylastch = yytext+yyleng-1; } loop: lsp = yylstate; state = yybgin; if (yyprevious==YYNEWLINE) state++; for (;;) { if ((r = state->yystoff) == 0) if((state= state->yyother) ==0) break; else r = state->yystoff; *yylastch++ = ch = input(); tryagain: r =+ ch; if (r->verify == state) *lsp++ = state = r->advance; else if ((state = state->yyother) && (r= state->yystoff)) goto tryagain; else { unput(*--yylastch); break; } } while (lsp-- > yylstate) { *yylastch-- = 0; if (*lsp != 0 && (yyfnd= (*lsp)->yystops) && *yyfnd > 0) { yyolsp = lsp; if (yyextra[*yyfnd]) { while (yyback((*lsp)->yystops, -*yyfnd) != 1 && lsp>yylstate) { lsp--; unput(*yylastch--); } } yyprevious = *yylastch; yylsp = lsp; yyleng = yylastch-yytext+1; yytext[yyleng] = 0; return(*yyfnd++); } unput(*yylastch); } if (yytext[0] == 0) return(0); output(yyprevious = input()); yylastch=yytext; goto loop; } yyback(p, m) int *p; { if (p==0) return(0); while (*p) { if (*p++ == m) return(1); } return(0); } *yyfnd > 0) { yyolsp = lsp; if (yyextra[*yyfnd]) { whil# int nar 0; int hflg, binflg; # define BINARY 1 # define HASH 2 extern char yytext[]; int nrule 0; char ruleid[50], size[50], exist[50], length[50]; int kind[100]; int estimate, method; # define name 257 # define number 258 # define Int 259 # define Char 260 # define String 261 # define Size 262 # define Exist 263 # define Method 264 #define yyclearin yychar = -1 #define yyerrok yyerrflag = 0 extern int yychar, yyerrflag; int yyval 0; int *yypv; int yylval 0; yyactr(__np__){ switch(__np__){ case 2: { nrule++; writeprog(); nar = 0; } break; case 3: { printf (-1, size, "%d", yypv[5]); } break; case 4: { printf(-1, size, "sizeof(%s)", length); } break; case 5: { printf(-1, size, "%d", sizeof(nrule)); } break; case 6:{ estimate=0; method = BINARY;} break; case 7:{estimate = yypv[2]; method = HASH;} break; case 8:{method = yypv[2];} break; case 9:{estimate= yypv[2]; method=yypv[3];} break; case 10:{copy (ruleid,yytext);} break; case 11:{copy(length, yytext);} break; case 12: { kind[nar++] = yypv[1]; } break; case 13: { kind[nar++] = yypv[3]; } break; case 14:{yyval= 'i';} break; case 15:{yyval = 'i';} break; case 16: {yyval = 's';} break; case 17: {yyval = 'z';} break; case 18: {yyval = 'e';} break; } } int yyerrval 256; # include "lex.yy.c" writeprog() { int i, szflg, eflg, p1, p2, p3, fs; char * mname, root[20]; szflg = eflg = -1; switch (method) { case BINARY: mname = "aabinary"; binflg=1; printf(-1, root, "%d", nrule); break; case HASH: mname = "aahash"; hflg=1; printf(-1, root, "aa%droot", nrule); p1 = nprime(estimate*3/2); p2 = nprime(p1); p3 = nprime(p2); printf("struct hnode{char *aakey, *aadata;} aa%droot[%d];\n", nrule, p3); printf("int aa%dtsize %d;\n", nrule, p3); printf("int aa%dp1 %d;\n", nrule,p1); printf("int aa%dp2 %d;\n", nrule, p2); break; } printf("%s",ruleid); printf( "(a0"); for(i=1; i 0) printf(-1, size, "a%d",szflg); printf(-1, exist, (eflg>0 ? "a%d" : "0"), eflg); if (method==HASH) { printf("\taatsize = aa%dtsize;\n", nrule); printf("\taapr1 = aa%dp1;\n", nrule); printf("\taapr2 = aa%dp2;\n", nrule); } printf(" return(%s(%s,keyi, kip-keyi, keyc, %s,%s));\n", mname, root, size,exist); printf("}\n"); } copy (s,t) char *s, *t; { while (*s++ = *t++); } # ifdef unix char *binnam "/usr/source/agen/aabin.c"; char *hshnam "/usr/source/agen/aahash.c"; char *subnam "/usr/source/agen/aasub.c"; # endif # ifdef gcos char *binnam "pounce/aabin.c"; char *hshnam "pounce/aahash.c"; char *subnam "pounce/aasub.c"; # endif main(argc,argv) char *argv[]; { extern int cin, cout; int c; cin = copen(argv[1], 'r'); cout = copen("a.tab.c", 'w'); printf("#\n"); yyparse(); while (c=cgetc(cin)) cputc(c,cout); cclose(cin); printf("struct node {char *aakey, *aadata; struct node *lp, *rp;};\n"); printf("struct node *aaroot[%d];\n",nrule+1); fcopy(subnam); if (binflg) fcopy(binnam); if (hflg) fcopy(hshnam); cexit(); } fcopy(s) char *s; { int c; extern int cin, cout; cin = copen(s, 'r'); while (c=cgetc(cin)) cputc(c,cout); } nprime(n) { while (!prime(++n)); return(n); } known[] {2,3,5,7,11,13,17,19,23,29,31,37,41, 43,47,53,59,61,67, 71,73,79,83,89,97,101,103,107,109, 113,127,131,137,139,149,151,157,163, 167,173,179,181,191,193,197,199,211,0}; prime(n) { int *p, k; p=known; while ((k= *p++) && (k*k <= n)) if (n%k==0) return(0); return(1); } int yyact[] {0,12289,4096,16384,4353,8197,0,12290,4136,8198 ,0,4354,8199,4360,8200,12294,12298,4355,8203,4356 ,8204,4357,8205,4358,8206,4359,8207,0,4360,8208 ,12295,12296,4137,8209,4140,8210,0,12300,12302,12303 ,12304,12305,12306,12297,4353,8214,4354,8211,4155,8213 ,0,4355,8203,4356,8204,4357,8205,4358,8206,4359 ,8207,0,4155,8216,0,4155,8217,0,12293,12299 ,12301,12291,12292,-1}; int yypact[] {0,1,2,7,8,11,16,17,28,31 ,32,37,38,39,40,41,42,43,44,51 ,62,65,68,69,70,71,72,-1}; int yyr1[] {0,1,1,2,2,2,3,3,3,3 ,6,5,4,4,7,7,7,7,7,-1}; int yyr2[] {0,0,2,6,6,5,1,2,2,3 ,1,1,1,3,1,1,1,1,1,-1}; int yygo[] {0,-1,1,-1,2,-1,3,-1,9,-1 ,20,-1,4,18,23,-1,10,-1}; int yypgo[] {0,1,3,5,7,9,11,13,-1}; int nterms 14; int nnonter 7; int nstate 26; char *yysterm[] { "error", "name", "number", "Int", "Char", "String", "Size", "Exist", "Method", 0 }; char *yysnter[] { "$accept", "S", "thing", "label", "arglist", "len", "rname", "type" }; ,32,37,38,39,40,41,42,43,44,51 ,62,65,68,69,70,71,72,-1}; int yyr1[] {0,1,1,2,2,2,3,3,3,3 ,6,5,4,4,7,7,7,7,7,-1}; int yyr2[] {0,0,2/ / / PDP-11 assembler pass 0 indir = 0 jmp start go: jsr pc,assem movb pof,r0 sys write; outbuf; 512. movb pof,r0 sys close movb fbfil,r0 sys close tstb errflg bne aexit jsr r5,fcreat; a.tmp3 mov r0,r1 mov symend,0f sub $usymtab,0f sys indir; 9f .data 9: sys write; usymtab; 0:.. .text mov r1,r0 sys close sys exec; fpass2; 1f mov $2f,r0 jsr r5,filerr; "?\n aexit: sys unlink; a.tmp1 sys unlink; a.tmp2 sys unlink; a.tmp3 mov $3,r0 sys exit .data 1: fpass2 globfl outfl outfp:  outfile a.tmp1 a.tmp2 a.tmp3 0 fpass2: globfl: unglob=.+1 <-\0\0> outfl: <-o\0> outfile: 3: <-g\0> .even .text filerr: mov r4,-(sp) mov r0,r4 mov r4,0f clr r0 1: tstb (r4)+ beq 1f inc r0 br 1b 1: mov r0,1f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 1:0 .text mov r5,0f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 2 .text tst (r5)+ mov (sp)+,r4 rts r5 fcreat: mov r4,-(sp) mov (r5)+,r4 mov r4,0f 1: sys indir; 9f .data 9: sys stat; 0:..; outbuf .text bec 2f mov r4,0f sys indir; 9f .data 9: sys creat; 0:..; 444 .text bes 2f mov (sp)+,r4 rts r5 2: incb 9.(r4) cmpb 9.(r4),$'z blos 1b mov r4,r0 jsr r5,filerr; "?\n mov $3,r0 sys exit 4)+ beq 1f inc r0 br 1b 1: mov r0,1f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 1:0 .text mov r5,0f mov $1,r0 sys indir; 9f .data 9: sys write; 0:0; 2 .text tst (r5)+ mov (sp)+,r4 rts r5 fcreat: mov r4,-(sp) mov (r5)+,r4 mov r4,0f 1: sys indir; 9f .data 9: sys stat; 0:..; o/ / / a2 -- pdp-11 assembler pass 1 error: incb errflg mov r0,-(sp) mov r1,-(sp) mov (r5)+,r0 tst *curarg beq 1f mov r0,-(sp) mov *curarg,r0 clr *curarg jsr r5,filerr; '\n mov (sp)+,r0 1: mov r2,-(sp) mov r3,-(sp) mov line,r3 movb r0,1f mov $1f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 1f; 7 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rts r5 .data 1: .even .text betwen: cmp r0,(r5)+ blt 1f  cmp (r5)+,r0 blt 2f 1: tst (r5)+ 2: rts r5 putw: tst ifflg beq 1f cmp r4,$'\n bne 2f 1: mov r4,*obufp add $2,obufp cmp obufp,$outbuf+512. blo 2f mov $outbuf,obufp movb pof,r0 sys write; outbuf; 512. 2: rts pc ) mov line,r3 movb r0,1f mov $1f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 1f; 7 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rts r5 .data 1: .even .text betwen: cmp r0,(r5)+ blt 1f / / / a3 -- pdp-11 assembler pass 1 assem: jsr pc,readop jsr pc,checkeos br ealoop tst ifflg beq 3f cmp r4,$200 blos assem cmpb (r4),$21 /if bne 2f inc ifflg 2: cmpb (r4),$22 /endif bne assem dec ifflg br assem 3: mov r4,-(sp) jsr pc,readop cmp r4,$'= beq 4f cmp r4,$': beq 1f mov r4,savop mov (sp)+,r4 jsr pc,opline br ealoop 1: mov (sp)+,r4 cmp r4,$200 bhis 1f cmp r4,$1 / digit beq 3f jsr r5,error; 'x br assem 1: bitb $37,(r4) beq 1f jsr r5,error; 'm 1: bisb dot-2,(r4) mov dot,2(r4) br assem 3: mov numval,r0 jsr pc,fbcheck movb dotrel,curfbr(r0) asl r0 movb dotrel,nxtfb mov dot,nxtfb+2 movb r0,nxtfb+1 mov dot,curfb(r0) movb fbfil,r0 sys write; nxtfb; 4 br assem 4: jsr pc,readop jsr pc,expres mov (sp)+,r1 cmp r1,$200 bhis 1f jsr r5,error; 'x br ealoop 1: cmp r1,$dotrel bne 2f bic $40,r3 cmp r3,dotrel bne 1f 2: bicb $37,(r1) bic $!37,r3 bne 2f clr r2 2: bisb r3,(r1) mov r2,2(r1) br ealoop 1: jsr r5,error; '. movb $2,dotrel ealoop: cmp r4,$'; beq assem1 cmp r4,$'\n bne 1f inc line br assem1 1: cmp r4,$'\e bne 2f tst ifflg beq 1f jsr r5,error; 'x 1: rts pc 2: jsr r5,error; 'x 2: jsr pc,checkeos br assem1 jsr pc,readop br 2b assem1: jmp assem fbcheck: cmp r0,$9. bhi 1f rts pc 1: jsr r5,error; 'f clr r0 rts pc checkeos: cmp r4,$'\n beq 1f cmp r4,$'; beq 1f cmp r4,$'\e beq 1f add $2,(sp) 1: rts pc ,r3 bne 2f clr r2 2: bisb r3,(r1) mov r2,2(r1) br ealoop 1: jsr r5,error; '. movb $2,dotrel ealoop: cmp r/ / / a4 -- pdp-11 assembler pass1 rname: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov $8,r5 mov $symbol+8.,r2 clr -(r2) clr -(r2) clr -(r2) clr -(r2) clr -(sp) clr -(sp) cmp r0,$'~ / symbol not for hash table bne 1f inc 2(sp) clr ch 1: jsr pc,rch movb chartab(r0),r3 ble 1f add r3,(sp) swab (sp) dec r5 blt 1b movb r3,(r2)+ br 1b 1: mov r0,ch mov (sp)+,r1 clr r0 tst (sp)+ beq 1f mov symend,r4 br 4f 1: div $hshsiz,r0 ashc $1,r0 add $hshtab,r1 1: sub r0,r1 cmp r1,$hshtab bhi 2f add $2*hshsiz,r1 2: mov $symbol,r2 mov -(r1),r4 beq 3f cmp (r2)+,(r4)+ bne 1b cmp (r2)+,(r4)+ bne 1b cmp (r2)+,(r4)+ bne 1b cmp (r2)+,(r4)+ bne 1b br 1f 3: mov symend,r4 mov r4,(r1) 4: mov $symbol,r2 mov r4,-(sp) add $20,r4 cmp r4,0f blos 4f add $512.,0f sys indir; 9f .data 9: sys break; 0:end .text 4: mov (sp)+,r4 mov (r2)+,(r4)+ mov (r2)+,(r4)+ mov (r2)+,(r4)+ mov (r2)+,(r4)+ clr (r4)+ clr (r4)+ mov r4,symend sub $4,r4 1: mov r4,-(sp) mov r4,r3 sub $8,r3 cmp r3,$usymtab blo 1f sub $usymtab,r3 clr r2 div $3,r2 mov r2,r4 add $4000,r4 / user symbol br 2f 1: sub $symtab,r3 clr r2 div $3,r2 mov r2,r4 add $1000,r4 / builtin symbol 2: jsr pc,putw mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 tst (sp)+ rts pc number: mov r2,-(sp) mov r3,-(sp) mov r5,-(sp) clr r1 clr r5 1: jsr pc,rch jsr r5,betwen; '0; '9 br 1f sub $'0,r0 mpy $10.,r5 add r0,r5 als $3,r1 add r0,r1 br 1b 1: cmp r0,$'b beq 1f cmp r0,$'f beq 1f cmp r0,$'. bne 2f mov r5,r1 clr r0 2: movb r0,ch mov r1,r0 mov (sp)+,r5 mov (sp)+,r3 mov (sp)+,r2 rts pc 1: mov r0,r3 mov r5,r0 jsr pc,fbcheck add $141,r0 cmp r3,$'b beq 1f add $10.,r0 1: mov r0,r4 mov (sp)+,r5 mov (sp)+,r3 mov (sp)+,r2 add $2,(sp) rts pc rch: movb ch,r0 beq 1f clrb ch rts pc 1: dec inbfcnt blt 2f movb *inbfp,r0 inc inbfp bic $!177,r0 beq 1b rts pc 2: movb fin,r0 beq 3f sys read; inbuf;512. bcs 2f tst r0 beq 2f mov r0,inbfcnt mov $inbuf,inbfp br 1b 2: movb fin,r0 clrb fin sys close 3: decb nargs bgt 2f mov $'\e,r0 rts pc 2: tst ifflg beq 2f jsr r5,error; 'i jmp aexit 2: mov curarg,r0 tst (r0)+ mov (r0),0f mov r0,curarg incb fileflg sys indir; 9f .data 9: sys open; 0:0; 0 .text bec 2f mov 0b,r0 jsr r5,filerr; jmp aexit 2: movb r0,fin mov $1,line mov r4,-(sp) mov r1,-(sp) mov $5,r4 jsr pc,putw mov *curarg,r1 2: movb (r1)+,r4 beq 2f jsr pc,putw br 2b 2: mov $-1,r4 jsr pc,putw mov (sp)+,r1 mov (sp)+,r4 br 1b 2: movb fin,r0 / / / a5 -- pdp-11 assembler pass 1 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,8f jsr pc,putw rts pc 8: jsr pc,rch _readop: mov r0,r4 movb chartab(r0),r1 bgt rdname jmp *1f-2(r1) fixor escp 8b retread dquote garb squote rdname skip rdnum retread string 1: escp: jsr pc,rch mov $esctab,r1 1: cmpb r0,(r1)+ beq 1f tstb (r1)+ bne 1b rts pc 1: movb (r1),r4 rts pc esctab: .byte '/, '/ .byte '\<, 035 .byte '>, 036 .byte '%, 037 .byte 0, 0 fixor: mov $037,r4 retread: rts pc rdname: movb r0,ch cmp r1,$'0 blo 1f cmp r1,$'9 blos rdnum 1: jmp rname rdnum: jsr pc,number br 1f rts pc squote: jsr pc,rsch br 1f dquote: jsr pc,rsch mov r0,-(sp) jsr pc,rsch swab r0 bis (sp)+,r0 1: mov r0,numval mov $1,r4 jsr pc,putw mov numval,r4 jsr pc,putw mov $1,r4 tst (sp)+ rts pc skip: jsr pc,rch mov r0,r4 cmp r0,$'\e beq 1f cmp r0,$'\n bne skip 1: rts pc garb: jsr r5,error; 'g br 8b string: mov $'<,r4 jsr pc,putw clr numval 1: jsr pc,rsch tst r1 bne 1f mov r0,r4 bis $400,r4 jsr pc,putw inc numval br 1b 1: mov $-1,r4 jsr pc,putw mov $'<,r4 tst (sp)+ rts pc rsch: jsr pc,rch cmp r0,$'\e beq 4f cmp r0,$'\n beq 4f clr r1 cmp r0,$'\\ bne 3f jsr pc,rch mov $schar,r2 1: cmpb (r2)+,r0 beq 2f tstb (r2)+ bpl 1b rts pc 2: movb (r2)+,r0 clr r1 rts pc 3: cmp r0,$'> bne 1f inc r1 1: rts pc 4: jsr r5,error; '< jmp aexit schar: .byte 'n, 012 .byte 's, 040 .byte 't, 011 .byte 'e, 004 .byte '0, 000 .byte 'r, 015 .byte 'a, 006 .byte 'p, 033 .byte 0, -1 sr pc,putw inc numval br 1b 1: mov $-1,r4 jsr pc,putw mov $'<,r4 tst (sp)+ rts pc rsch: jsr pc,rch cmp r0,$'\e beq 4f cmp r0,$'\n beq 4f clr r1 cmp r0,$'\\ bne 3f jsr pc,rch mov $schar,r2 1: cmpb (r2)+,r0 beq 2f tstb (r2)+ bpl 1b rts pc 2: movb (r2)+,r0 clr r1 rts pc 3: cmp r0,$'> bne 1f inc r1 1: rts pc 4: jsr r5,error; '< jmp aexit schar: .byte 'n, 012 .byte 's, 040 .byte 't, 011 .byte 'e, 004 .byte '0, 000 .byte 'r, 015 / / / a6 -- pdp-11 assembler pass 1 opline: mov r4,r0 jsr r5,betwen; 0; 200 br 1f cmp r0,$'< bne xpr jmp opl17 xpr: jsr pc,expres add $2,dot rts pc 1: movb (r4),r0 cmp r0,$24 beq xpr jsr r5,betwen; 5; 36 br xpr mov r0,-(sp) jsr pc,readop mov (sp)+,r0 asl r0 jmp *1f-12(r0) 1: opl13 / map fop freg,fdst to double opl6 opl7 opl10 opl11 opl13 / map fld/fst to double opl13 opl13 / map fop fsrc,freg to double opl15 opl16 opl17 opl20 opl21 opl22 opl23 xpr opl25 opl26 opl27 opl13 / map mul s,r to double opl31 opl32 xpr xpr opl35 opl36 / jbr opl35: mov $4,-(sp) br 1f / jeq, etc opl36: mov $6,-(sp) 1: jsr pc,expres cmp r3,dotrel bne 1f sub dot,r2 bge 1f cmp r2,$-376 blt 1f mov $2,(sp) 1: add (sp)+,dot rts pc /double opl13: opl7: jsr pc,addres op2: cmp r4,$', beq 1f jsr pc,errora rts pc 1: jsr pc,readop opl15: / single operand jsr pc,addres add $2,dot rts pc opl31: / sob jsr pc,expres cmp r4,$', beq 1f jsr pc,errora 1: jsr pc,readop /branch opl6: opl10: opl11: jsr pc,expres add $2,dot rts pc / .byte opl16: jsr pc,expres inc dot cmp r4,$', bne 1f jsr pc,readop br opl16 1: rts pc / < (.ascii) opl17: add numval,dot jsr pc,readop rts pc /.even opl20: inc dot bic $1,dot rts pc /.if opl21: jsr pc,expres tst r3 bne 1f jsr r5,error; 'U 1: tst r2 bne opl22 inc ifflg opl22: /endif rts pc /.globl opl23: cmp r4,$200 blo 1f bisb $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop br opl23 1: rts pc opl25: opl26: opl27: mov dotrel,r1 asl r1 mov dot,savdot-4(r1) mov savdot-[2*25](r0),dot asr r0 sub $25-2,r0 mov r0,dotrel rts pc / .common opl32: cmp r4,$200 blo 1f bis $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop jsr pc,expres rts pc 1: jsr r5,error; 'x rts pc addres: cmp r4,$'( beq alp cmp r4,$'- beq amin cmp r4,$'$ beq adoll cmp r4,$'* beq astar getx: jsr pc,expres cmp r4,$'( bne 2f jsr pc,readop jsr pc,expres jsr pc,checkreg jsr pc,checkrp add $2,dot clr r0 rts pc 2: cmp r3,$24 / register type bne 1f jsr pc,checkreg clr r0 rts pc 1: add $2,dot clr r0 rts pc alp: jsr pc,readop jsr pc,expres jsr pc,checkrp jsr pc,checkreg cmp r4,$'+ bne 1f jsr pc,readop clr r0 rts pc 1: mov $2,r0 rts pc amin: jsr pc,readop cmp r4,$'( beq 1f mov r4,savop mov $'-,r4 br getx 1: jsr pc,readop jsr pc,expres jsr pc,checkrp jsr pc,checkreg clr r0 rts pc adoll: jsr pc,readop jsr pc,expres add $2,dot clr r0 rts pc astar: jsr pc,readop cmp r4,$'* bne 1f jsr r5,error; '* 1: jsr pc,addres add r0,dot rts pc errora: jsr r5,error; 'a rts pc checkreg: cmp r2,$7 bhi 1f cmp r3,$1 beq 2f cmp r3,$4 bhi 2f 1: jsr pc,errora 2: rts pc errore: jsr r5,error; 'e rts pc checkrp: cmp r4,$') beq 1f jsr r5,error; ') rts pc 1: jsr pc,readop rts pc '-,r4 br getx 1: jsr pc,readop jsr pc,expres jsr pc,checkrp jsr pc,checkreg clr r0 rts pc adoll: jsr pc,readop jsr pc,expres add $2,dot clr r0 rts pc astar: jsr pc,readop cmp r4,$'* bne 1f/ / / a7 -- pdp-11 assembler pass 1 expres: mov r5,-(sp) mov $'+,-(sp) clr opfound clr r2 mov $1,r3 br 1f advanc: jsr pc,readop 1: mov r4,r0 jsr r5,betwen; 0; 177 br .+4 br 7f movb (r4),r0 mov 2(r4),r1 br oprand 7: cmp r4,$141 blo 1f cmp r4,$141+10. bhis 2f movb curfbr-141(r4),r0 asl r4 mov curfb-[2*141](r4),r2 bpl oprand jsr r5,error; 'f br oprand 2: clr r3 clr r2 br oprand 1: mov $esw1,r1 1: cmp (r1)+,r4 beq 1f tst (r1)+ bne 1b tst opfound bne 2f jsr pc,errore 2: tst (sp)+ mov (sp)+,r5 rts pc 1: jmp *(r1) esw1: '+; binop '-; binop '*; binop '/; binop '&; binop 037; binop 035; binop 036; binop '%; binop '[; brack '^; binop 1; exnum '!; binop 0; 0 binop: cmpb (sp),$'+ beq 1f jsr pc,errore 1: movb r4,(sp) br advanc exnum: mov numval,r1 mov $1,r0 br oprand brack: mov r2,-(sp) mov r3,-(sp) jsr pc,readop jsr pc,expres cmp r4,$'] beq 1f jsr r5,error; '] 1: mov r3,r0 mov r2,r1 mov (sp)+,r3 mov (sp)+,r2 oprand: inc opfound mov $exsw2,r5 1: cmp (sp),(r5)+ beq 1f tst (r5)+ bne 1b br eoprnd 1: jmp *(r5) exsw2: '+; exadd '-; exsub '*; exmul '/; exdiv 037; exor '&; exand 035;exlsh 036;exrsh '%; exmod '!; exnot '^; excmbin 0; 0 excmbin: mov r0,r3 / give left flag of right br eoprnd exrsh: neg r1 beq exlsh inc r1 clc ror r2 exlsh: jsr r5,combin; 0 als r1,r2 br eoprnd exmod: jsr r5,combin; 0 mov r1,-(sp) mov r2,r1 clr r0 dvd (sp)+,r0 mov r1,r2 br eoprnd exadd: jsr r5,combin; 0 add r1,r2 br eoprnd exsub: jsr r5,combin; 1 sub r1,r2 br eoprnd exand: jsr r5,combin; 0 com r1 bic r1,r2 br eoprnd exor: jsr r5,combin; 0 bis r1,r2 br eoprnd exmul: jsr r5,combin; 0 mpy r2,r1 mov r1,r2 br eoprnd exdiv: jsr r5,combin; 0 mov r1,-(sp) mov r2,r1 clr r0 dvd (sp)+,r0 mov r0,r2 br eoprnd exnot: jsr r5,combin; 0 com r1 add r1,r2 br eoprnd eoprnd: mov $'+,(sp) jmp advanc combin: mov r0,-(sp) bis r3,(sp) bic $!40,(sp) bic $!37,r0 bic $!37,r3 cmp r0,r3 ble 1f mov r0,-(sp) mov r3,r0 mov (sp)+,r3 1: tst r0 beq 1f tst (r5)+ beq 2f cmp r0,r3 bne 2f mov $1,r3 br 2f 1: tst (r5)+ clr r3 2: bis (sp)+,r3 rts r5 r eoprnd exmul: jsr r5,combin; 0 mpy r2,r1 mov r1,r2 br eoprnd exdiv: jsr r5,combin; 0 mov r1,-(sp) mov r2,r1 clr r0 dvd (sp)+,r0 mov r0,r2 br eoprnd exnot: jsr r5,combin; 0 com r1 add r1,r2 br eoprnd eoprnd: mov $'+,(sp) jmp advanc combin: mov r0,-(sp) bis r3,(sp) bic $!40,(sp) bic $!37,r0 bic $!37,r3 cmp r0,r3 ble 1f mov r0,-(sp) mov r3,/ / / a8 -- pdp-11 assembler pass 1 chartab: .byte -14,-14,-14,-14,-02,-14,-14,-14 .byte -14,-22, -2,-14,-14,-22,-14,-14 .byte -14,-14,-14,-14,-14,-14,-14,-14 .byte -14,-14,-14,-14,-14,-14,-14,-14 .byte -22,-20,-16,-14,-20,-20,-20,-12 .byte -20,-20,-20,-20,-20,-20,056,-06 .byte 060,061,062,063,064,065,066,067 .byte 070,071,-20,-02,-00,-20,-14,-14 .byte -14,101,102,103,104,105,106,107 .byte 110,111,112,113,114,115,116,117 .byte 120,121,122,123,124,125,126,127 .byte 130,131,132,-20,-24,-20,-20,137 .byte -14,141,142,143,144,145,146,147 .byte 150,151,152,153,154,155,156,157 .byte 160,161,162,163,164,165,166,167 .byte 170,171,172,-14,-26,-14,176,-14 .data namedone:.byte 0 a.tmp1: a.tmp2: a.tmp3: .even curfb: -1;-1;-1;-1;-1;-1;-1;-1;-1;-1 obufp: outbuf symend: usymtab .bss curfbr: .=.+10. savdot: .=.+6 bufcnt: .=.+2 hshsiz = 2003. hshtab: .=2*hshsiz+. pof: .=.+1 wordf: .=.+1 fin: .=.+1 fbfil: .=.+1 fileflg:.=.+1 errflg: .=.+1 ch: .=.+1 .even symbol: .=.+8. obufc: .=.+2 outbuf: .=.+512. line: .=.+2 inbfcnt:.=.+2 ifflg: .=.+2 inbfp: .=.+2 nargs: .=.+2 curarg: .=.+2 opfound:.=.+2 savop: .=.+2 numval: .=.+2 nxtfb: .=.+4 usymtab:.=.+36. end: .text tm1a\0> a.tmp2: a.tmp3: .even curfb: -1;-1;-1;-1;-1;-1;-1;-1;-1;-1 obufp: outbuf symend: usymtab .bss curfbr: .=.+10. savdot: .=.+6 bufcnt: .=.+2 hshsiz = 2003. hshtab: .=2*hshsiz+. pof: .=.+1 wordf: .=.+1 fin: .=.+1 fbfil: .=.+1 fileflg:.=.+1 errflg: .=.+1 ch: .=.+1 .even symbol/ / / a9 -- pdp-11 assembler pass 1 eae = 0 / key to types / 0 undefined / 1 absolute / 2 text / 3 data / 4 bss / 5 flop freg,dst (movfo, = stcfd) / 6 branch / 7 jsr / 10 rts / 11 sys / 12 movf (=ldf,stf) / 13 double operand (mov) / 14 flop fsrc,freg (addf) / 15 single operand (clr) / 16 .byte / 17 string (.ascii, "<") / 20 .even / 21 .if / 22 .endif / 23 .globl / 24 register / 25 .text / 26 .data / 27 .bss / 30 mul,div, etc / 31 sob / 32 .comm / 33 estimated text / 34 estimated data / 35 jbr / 36 jeq, jne, etc .data symtab: / special variables <.\0\0\0\0\0\0\0>; dotrel:02; dot:000000 <..\0\0\0\0\0\0>; 01; dotdot:000000 / register ; 24;000000 ; 24;000001 ; 24;000002 ; 24;000003 ; 24;000004 ; 24;000005 ; 24;000006 ; 24;000007 .if eae /eae & switches ; 01;177570 ; 01;177300 ; 01;177302 ; 01;177304 ; 01;177306 ; 01;177310 ; 01;177311 ; 01;177312 ; 01;177314 ; 01;177316 .endif / system calls ; 01;0000000 ; 01;0000001 ; 01;0000002 ; 01;0000003 ; 01;0000004 ; 01;0000005 ; 01;0000006 ; 01;0000007 ; 01;0000010 ; 01;0000011 ; 01;0000012 ; 01;0000013 ; 01;0000014 ; 01;0000015 ; 01;0000016 ; 01;0000017 ; 01;0000020 ; 01;0000021 ; 01;0000022 ; 01;0000023 ; 01;0000024 ; 01;0000025 ; 01;0000026 ; 01;0000027 ; 01;0000030 ; 01;0000031 ; 01;0000032 ; 01;0000034 ; 01;0000037 ; 01;0000040 ; 01;0000042 ; 01;0000043 ; 01;0000044 ; 01;0000045 ; 01;0000046 ; 01;0000051 ; 01;0000052 ; 01;0000053 ; 01;0000054 ; 01;0000056 ; 01;0000057 ; 01;0000060 / double operand ; 13;0010000 ; 13;0110000 ; 13;0020000 ; 13;0120000 ; 13;0030000 ; 13;0130000 ; 13;0040000 ; 13;0140000 ; 13;0050000 ; 13;0150000 ; 13;0060000 ; 13;0160000 / branch ; 06;0000400 ; 06;0001000 ; 06;0001400 ; 06;0002000 ; 06;0002400 ; 06;0003000 ; 06;0003400 ; 06;0100000 ; 06;0100400 ; 06;0101000 ; 06;0101400 ; 06;0102000 ; 06;0102400 <bhis\0\0\0\0>; 06;0103000 ; 06;0103000 ; 06;0103000 ; 06;0103400 ; 06;0103400 ; 06;0103400 / jump/branch type ; 35;0000400 ; 36;0001000 ; 36;0001400 ; 36;0002000 ; 36;0002400 ; 36;0003000 ; 36;0003400 ; 36;0100000 ; 36;0100400 ; 36;0101000 ; 36;0101400 ; 36;0102000 ; 36;0102400 ; 36;0103000 ; 36;0103000 ; 36;0103000 ; 36;0103400 ; 36;0103400 ; 36;0103400 / single operand ; 15;0005000 ; 15;0105000 ; 15;0005100 ; 15;0105100 ; 15;0005200 ; 15;0105200 ; 15;0005300 ; 15;0105300 ; 15;0005400 ; 15;0105400 ; 15;0005500 ; 15;0105500 ; 15;0005600 ; 15;0105600 ; 15;0005700 ; 15;0105700 ; 15;0006000 ; 15;0106000 ; 15;0006100 ; 15;0106100 ; 15;0006200 ; 15;0106200 ; 15;0006300 ; 15;0106300 ; 15;0000100 ; 15;0000300 / jsr ; 07;0004000 / rts ; 010;000200 / simple operand ; 011;104400 / flag-setting ; 01;0000241 ; 01;0000242 ; 01;0000244 ; 01;0000250 ; 01;0000261 ; 01;0000262 ; 01;0000264 ; 01;0000270 / floating point ops ; 01;170000 ; 01;170001 ; 01;170011 ; 01;170002 ; 01;170012 ; 15;170400 ; 15;170700 ; 15;170600 ; 15;170500 ; 12;172400 ; 14;177000 ; 05;175400 ; 14;177400 ; 05;176000 ; 14;172000 ; 14;173000 ; 14;171000 ; 14;174400 ; 14;173400 ; 14;171400 ; 14;176400 ; 05;175000 ; 15;170100 ; 15;170200 ; 24;000000 ; 24;000001 ; 24;000002 ; 24;000003 ; 24;000004 ; 24;000005 / 11/45 operations ; 30;072000 ; 30;073000 ; 30;070000 .if eae-1 ; 30;070000 ; 30;071000 ; 30;072000 ; 30;073000 .endif ; 30;071000 ; 07;074000 ; 15;006700 ; 11;006400 ; 31;077000 / specials <.byte\0\0\0>; 16;000000 <.even\0\0\0>; 20;000000 <.if\0\0\0\0\0>; 21;000000 <.endif\0\0>; 22;000000 <.globl\0\0>; 23;000000 <.text\0\0\0>; 25;000000 <.data\0\0\0>; 26;000000 <.bss\0\0\0\0>; 27;000000 <.comm\0\0\0>; 32;000000 ebsymtab: start: sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; aexit 1: mov (sp)+,r0 tst (sp)+ 1: mov (sp),r1 cmpb (r1),$'- bne 1f tst (sp)+ dec r0 cmpb 1(r1),$'u bne 2f movb $'g,unglob br 1b 2: tstb 1(r1) bne 2f movb $'g,unglob br 1b 2: cmpb 1(r1),$'o bne 1f mov (sp),outfp tst (sp)+ dec r0 br 1b 1: movb r0,nargs tst -(sp) mov sp,curarg jsr r5,fcreat; a.tmp1 movb r0,pof jsr r5,fcreat; a.tmp2 movb r0,fbfil jsr pc,setup jmp go setup: mov $symtab,r1 1: clr r3 mov $8,r2 mov r1,-(sp) 2: movb (r1)+,r4 beq 2f add r4,r3 swab r3 sob r2,2b 2: clr r2 div $hshsiz,r2 ashc $1,r2 add $hshtab,r3 4: sub r2,r3 cmp r3,$hshtab bhi 3f add $2*hshsiz,r3 3: tst -(r3) bne 4b mov (sp)+,r1 mov r1,(r3) add $12.,r1 cmp r1,$ebsymtab blo 1b rts pc /overlay buffer inbuf = setup . =inbuf+512.  b 1: movb r0,nargs tst -(sp) mov sp,curarg jsr r5,fcreat; a.tmp1 movb r0,pof jsr r5,fcreat; a.tmp2 movb r0,fbfil jsr pc,setup jmp go setup: mov $symtab,r1 1: clr r3 mov $8,r2 mov r1,-(sp) 2: movb (r1)+,r4 beq 2f add r4,r3 swab r3 sob r2,2b 2: clr r2 div $hshsiz,r2 ashc $1,r2 add $hshtab,r3 4: sub r2,r3 cmp r3,$hshtab bhi 3f add $2*hshsiz,r3 3: tst -(r3) bne 4b mov (sp)+,r1 mov r1,(r3) add $12.,r1 cmp r1,$ebsymtab blo 1b rts pc /overlay buffer inbuf = setup . =inbuf+512. / / / a21 -- pdp-11 assembler pass 2 indir = 0 main: sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; saexit 1: jmp start / set up sizes and origins go: / read in symbol table mov $usymtab,r1 1: jsr pc,getw bvs 1f add $14,symsiz / count symbols jsr pc,getw jsr pc,getw jsr pc,getw jsr pc,getw mov r4,r0 bic $!37,r0 cmp r0,$2 /text blo 2f cmp r0,$3 /data bhi 2f add $31,r4 /mark "estimated" mov r4,(r1)+ jsr pc,getw mov r4,(r1)+ br 3f 2: clr (r1)+ clr (r1)+ jsr pc,getw 3: jsr pc,setbrk br 1b 1: / read in f-b definitions mov r1,fbbufp movb fbfil,fin clr ibufc 1: jsr pc,getw bvs 1f add $31,r4 / "estimated" mov r4,(r1)+ jsr pc,getw mov r4,(r1)+ jsr pc,setbrk br 1b 1: mov r1,endtable mov $100000,(r1)+ / set up input text file; initialize f-b table jsr pc,setup / do pass 1 jsr pc,assem / prepare for pass 2 cmp outmod,$777 beq 1f jmp aexit 1: clr dot mov $2,dotrel mov $..,dotdot clr brtabp movb fin,r0 sys close jsr r5,ofile; a.tmp1 movb r0,fin clr ibufc jsr pc,setup inc passno inc bsssiz bic $1,bsssiz mov txtsiz,r1 inc r1 bic $1,r1 mov r1,txtsiz mov datsiz,r2 inc r2 bic $1,r2 mov r2,datsiz mov r1,r3 mov r3,datbase / txtsiz mov r3,savdot+2 add r2,r3 mov r3,bssbase / txtsiz+datsiz mov r3,savdot+4 asl r3 add $20,r3 mov r3,symseek / 2*txtsiz+2*datsiz+20 sub r2,r3 mov r3,drelseek / 2*txtsiz+datsiz sub r1,r3 mov r3,trelseek / txtsiz+datsiz+20 sub r2,r3 mov r3,datseek / txtsiz+20 mov $usymtab,r1 1: jsr pc,doreloc add $4,r1 cmp r1,endtable blo 1b clr r0 jsr r5,oset; txtp mov trelseek,r0 jsr r5,oset; relp mov $8.,r2 mov $txtmagic,r1 1: mov (r1)+,r0 jsr r5,putw; txtp dec r2 bne 1b jsr pc,assem /polish off text and relocation jsr r5,flush; txtp jsr r5,flush; relp / append full symbol table mov symf,r0 mov r0,fin sys seek; 0; 0; clr ibufc mov symseek,r0 jsr r5,oset; txtp mov $usymtab,r1 1: jsr pc,getw bvs 1f mov r4,r0 jsr r5,putw; txtp jsr pc,getw mov r4,r0 jsr r5,putw; txtp jsr pc,getw mov r4,r0  jsr r5,putw; txtp jsr pc,getw mov r4,r0 jsr r5,putw; txtp mov (r1)+,r0 jsr r5,putw; txtp mov (r1)+,r0 jsr r5,putw; txtp jsr pc,getw jsr pc,getw br 1b 1: jsr r5,flush; txtp jmp aexit .data saexit: mov pc,errflg aexit: mov a.tmp1,0f sys unlink; 0:.. mov a.tmp2,0f sys unlink; 0:.. mov a.tmp3,0f sys unlink; 0:.. sys chmod; a.outp2:a.out; outmod: 777 clr r0 tst errflg beq 1f inc r0 1: cmp $777,outmod beq 1f inc r0 1: sys exit .text filerr: mov *(r5),r5 1: movb (r5)+,ch beq 1f mov $1,r0 sys write; ch; 1 br 1b 1: mov $1,r0 sys write; qnl; 2 jmp aexit doreloc: movb (r1),r0 bne 1f bisb defund,(r1) 1: bic $!37,r0 cmp r0,$5 bhis 1f cmp r0,$3 blo 1f beq 2f add bssbase,2(r1) rts pc 2: add datbase,2(r1) 1: rts pc setbrk: mov r1,-(sp) add $20,r1 cmp r1,0f blo 1f add $512.,0f sys indir; 9f .data 9: sys break; 0: end .text 1: mov (sp)+,r1 rts pc setup: mov $curfb,r4 1: clr (r4)+ cmp r4,$curfb+40. blo 1b mov txtfil,fin clr ibufc clr r4 1: jsr pc,fbadv tstb (r4)+ cmp r4,$10. blt 1b rts pc ofile: mov *(r5),0f sys indir; 9f .data 9: sys open; 0:..; 0 .text bes 1f tst (r5)+ rts r5 1: jmp filerr 5 bhis 1f cmp r0,$3 blo 1f beq 2f add bssbase,2(r1) rts pc 2: add datbase,2(r1) 1: rts pc setbrk: mov r1,-(sp) add $20,r1 cmp r1,0f blo 1f add $512.,0f sys indir; 9f .data 9: sys break; 0: end .text 1: mov (sp)+,r1 rts pc setup: mov $curfb,r4 1: clr (r4)+ cmp r4,$curfb+40. blo 1b mov txtfil,fin clr ibufc clr r4 1: jsr pc,fbadv/ / / a2 -- pdp-11 assembler pass 2 outw: cmp dot-2,$4 beq 9f bit $1,dot bne 1f add $2,dot tstb passno beq 8f clr -(sp) rol r3 adc (sp) asr r3 / get relative pc bit cmp r3,$40 bne 2f / external references mov $666,outmod / make nonexecutable mov xsymbol,r3 sub $usymtab,r3 asl r3 bis $4,r3 / external relocation br 3f 2: bic $40,r3 / clear any ext bits cmp r3,$5 blo 4f cmp r3,$33 / est. text, data beq 6f cmp r3,$34 bne 7f 6: jsr r5,error; 'r 7: mov $1,r3 / make absolute 4:  cmp r3,$2 blo 5f cmp r3,$4 bhi 5f tst (sp) bne 4f add dotdot,r2 br 4f 5: tst (sp) beq 4f sub dotdot,r2 4: dec r3 bpl 3f clr r3 3: asl r3 bis (sp)+,r3 mov r2,r0 jsr r5,putw; txtp add $2,*tseekp mov r3,r0 jsr r5,putw; relp add $2,*rseekp 8: rts pc 1: jsr r5,error; 'o clr r3 jsr pc,outb rts pc 9: jsr r5,error; 'x rts pc outb: cmp dot-2,$4 / test bss mode beq 9b cmp r3,$1 blos 1f jsr r5,error; 'r 1: tstb passno beq 2f mov r2,r0 bit $1,dot bne 1f jsr r5,putw; txtp clr r0 jsr r5,putw; relp add $2,*rseekp add $2,*tseekp br 2f 1: mov txtp,r0 movb r2,-1(r0) 2: inc dot rts pc error: mov pc,errflg mov $666,outmod / make nonexecutable mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov $argb,r1 1: movb (r1),ch beq 1f clrb (r1)+ mov $1,r0 sys write; ch; 1 br 1b 1: mov (r5)+,r0 movb r0,0f mov line,r3 mov $0f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 0f; 7 mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 rts r5 .data 0: .even .text betwen: cmp r0,(r5)+ blt 1f cmp (r5)+,r0 blt 2f 1: tst (r5)+ 2: rts r5 / make nonexecutable mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov $argb,r1 1: movb (r1),ch beq 1f clrb (r1)+ mov $1,r0 sys write; ch; 1 br 1b 1: mov (r5)+,r0 movb r0,0f mov line,r3 mov $0f+6,r0 mov $4,r1 2: clr r2 dvd $10.,r2 add $'0,r3 movb r3,-(r0) mov r2,r3 sob r1,2b mov $1,r0 sys write; 0f; 7 mov (sp)+,r0 mov (sp)+,/ / / a3 -- pdp-11 assembler pass 2 assem: jsr pc,readop cmp r4,$5 beq 2f cmp r4,$'< beq 2f jsr pc,checkeos br eal1 mov r4,-(sp) cmp (sp),$1 bne 1f mov $2,(sp) jsr pc,getw mov r4,numval 1: jsr pc,readop cmp r4,$'= beq 4f cmp r4,$': beq 1f mov r4,savop mov (sp)+,r4 2: jsr pc,opline dotmax: tstb passno bne eal1 movb dotrel,r0 asl r0 cmp dot,txtsiz-4(r0) blos ealoop mov dot,txtsiz-4(r0) eal1: jmp ealoop 1: mov (sp)+,r4 cmp r4,$200 bhis 1f cmp r4,$2 beq 3f jsr r5,error; 'x  br assem 1: tstb passno bne 2f movb (r4),r0 bic $!37,r0 beq 5f cmp r0,$33 blt 6f cmp r0,$34 ble 5f 6: jsr r5,error; 'm 5: bic $37,(r4) bis dotrel,(r4) mov 2(r4),brdelt sub dot,brdelt mov dot,2(r4) br assem 2: cmp dot,2(r4) beq assem jsr r5,error; 'p br assem 3: mov numval,r4 jsr pc,fbadv asl r4 mov curfb(r4),r0 movb dotrel,(r0) mov 2(r0),brdelt sub dot,brdelt mov dot,2(r0) br assem 4: jsr pc,readop jsr pc,expres mov (sp)+,r1 cmp r1,$symtab /test for dot bne 1f bic $40,r3  cmp r3,dotrel / can't change relocation bne 2f cmp r3,$4 / bss bne 3f mov r2,dot br dotmax 3: sub dot,r2 bmi 2f mov r2,-(sp) 3: dec (sp) bmi 3f clr r2 mov $1,r3 jsr pc,outb br 3b 3: tst (sp)+ br dotmax 2: jsr r5,error; '. br ealoop 1: cmp r3,$40 bne 1f jsr r5,error; 'r 1: bic $37,(r1) bic $!37,r3 bne 1f clr r2 1: bisb r3,(r1) mov r2,2(r1) ealoop: cmp r4,$'\n beq 1f cmp r4,$'\e bne 9f rts pc 1: inc line 9: jmp assem checkeos: cmp r4,$'\n beq 1f cmp r4,$'; beq 1f cmp r4,$'\e beq 1f add $2,(sp) 1: rts pc fbadv: asl r4 mov nxtfb(r4),r1 mov r1,curfb(r4) bne 1f mov fbbufp,r1 br 2f 1: add $4,r1 2: cmpb 1(r1),r4 beq 1f tst (r1) bpl 1b 1: mov r1,nxtfb(r4) asr r4 rts pc 2: jsr r5,error; '. br ealoop 1: cmp r3,$40 bne 1f jsr r5,error; 'r 1: bic $37,(r1) bic $!37,r3 bne 1f clr r2 1: bisb r3,(r1) mov r2,2(r1) ealoop: cmp r4,$'\n beq 1f cmp r4,$'\e bne 9f rts pc 1: inc line 9: jmp assem checkeos: cmp r4,$'\n beq 1f cmp r4,$'; beq 1f cmp/ / / a4 -- pdp-11 assembler pass 2 oset: mov r2,-(sp) mov (r5)+,r1 mov r0,r2 bic $!777,r0 add r1,r0 add $6,r0 mov r0,(r1)+ / next slot mov r1,r0 add $1004,r0 mov r0,(r1)+ / buf max mov r2,(r1)+ / seek addr mov (sp)+,r2 rts r5 putw: mov r1,-(sp) mov r2,-(sp) mov (r5)+,r2 mov (r2)+,r1 / slot cmp r1,(r2) / buf max bhis 1f mov r0,(r1)+ mov r1,-(r2) br 2f 1: tst (r2)+ mov r0,-(sp) jsr r5,flush1 mov (sp)+,r0 mov r0,*(r2)+ add $2,-(r2) 2: mov (sp)+,r2 mov (sp)+,r1 rts r5 flush: mov (r5)+,r2 cmp (r2)+,(r2)+ flush1: mov (r2)+,r1 mov r1,0f / seek address mov fout,r0 sys indir; 9f .data 9: sys seek; 0:..; 0 .text bic $!777,r1 add r2,r1 / write address mov r1,0f mov r2,r0 bis $777,-(r2) inc (r2) / new seek addr cmp -(r2),-(r2) sub (r2),r1 neg r1 mov r1,0f+2 / count mov r0,(r2) / new next slot mov fout,r0 sys indir; 9f .data 9: sys write; 0:..; .. .text rts r5 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,getw1 cmp r4,$200 blo 1f cmp r4,$4000 blo 2f add $usymtab-4000,r4 rts pc 2: add $symtab-1000,r4 1: rts pc getw: mov savop,r4 beq getw1 clr savop rts pc getw1: dec ibufc bgt 1f movb fin,r0 sys read; inbuf; 512. bes 3f asr r0 mov r0,ibufc bne 2f 3: mov $4,r4 sev rts pc 2: mov $inbuf,ibufp 1: mov *ibufp,r4 add $2,ibufp rts pc r0,(r2) / new next slot mov fout,r0 sys indir; 9f .data 9: sys write; 0:..; .. .text rts r5 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,getw1 cmp r4,$200 blo 1f cmp r4,$4/ / / as25 is empty mtab-4000,r4 rts pc 2: add $symtab-1000,r4 1: rts pc getw: mov savop,r4 beq getw1 clr savop rts pc getw1: dec ibufc bgt 1f movb fin,r0 sys read; inbuf; 512. bes 3f asr r0 mov r0,ibufc bne 2f 3: mov $4,r4 sev rts pc 2: mov $inbuf,ibufp 1: mov *ibufp,r4 add $2,ibufp rts pc r0,(r2) / new next slot mov fout,r0 sys indir; 9f .data 9: sys write; 0:..; .. .text rts r5 readop: mov savop,r4 beq 1f clr savop rts pc 1: jsr pc,getw1 cmp r4,$200 blo 1f cmp r4,$4/ / / a6 -- pdp-11 assembler pass 2 opline: mov r4,r0 jsr r5,betwen; 0; 177 br 2f cmp r4,$5 beq opeof cmp r4,$'< bne xpr jmp opl17 xxpr: tst (sp)+ xpr: jsr pc,expres jsr pc,outw rts pc 2: movb (r4),r0 cmp r0,$24 /reg beq xpr cmp r0,$33 /est text beq xpr cmp r0,$34 / est data beq xpr jsr r5,betwen; 5; 36 br xpr mov 2(r4),-(sp) mov r0,-(sp) jsr pc,readop mov (sp)+,r0 asl r0 mov $adrbuf,r5 clr swapf mov $-1,rlimit jmp *1f-10.(r0) 1: opl5 opl6 opl7 opl10 opl11 opl12 opl13 opl14 opl15 opl16 opl17 opl20 opl21 opl22 opl23 xxpr opl25 opl26 opl27 opl30 opl31 opl32 xxpr xxpr opl35 opl36 opeof: mov $1,line mov $20,-(sp) mov $argb,r1 1: jsr pc,getw tst r4 bmi 1f movb r4,(r1)+ dec (sp) bgt 1b tstb -(r1) br 1b 1: movb $'\n,(r1)+ clrb (r1)+ tst (sp)+ rts pc opl30: / mpy, dvd etc inc swapf mov $1000,rlimit br opl13 opl14: / flop freg,fsrc inc swapf opl5: / flop src,freg mov $400,rlimit /double opl13: jsr pc,addres op2a: mov r2,-(sp)  jsr pc,readop op2b: jsr pc,addres tst swapf beq 1f mov (sp),r0 mov r2,(sp) mov r0,r2 1: swab (sp) asr (sp) asr (sp) cmp (sp),rlimit blo 1f jsr r5,error; 'x 1: bis (sp)+,r2 bis (sp)+,r2 clr r3 jsr pc,outw mov $adrbuf,r1 1: cmp r1,r5 bhis 1f mov (r1)+,r2 mov (r1)+,r3 mov (r1)+,xsymbol jsr pc,outw br 1b 1: rts pc opl15: / single operand clr -(sp) br op2b opl12: / movf mov $400,rlimit jsr pc,addres cmp r2,$4 / see if source is fregister blo 1f inc swapf br op2a 1: mov $174000,(sp) br op2a / jbr opl35: / jeq, jne, etc opl36: jsr pc,expres tstb passno bne 1f mov r2,r0 jsr pc,setbr tst r2 beq 2f cmp (sp),$br beq 2f add $2,r2 2: add r2,dot / if doesn't fit add $2,dot tst (sp)+ rts pc 1: jsr pc,getbr bcc dobranch mov (sp)+,r0 mov r2,-(sp) mov r3,-(sp) cmp r0,$br beq 2f mov $402,r2 xor r0,r2 / flip cond, add ".+6" mov $1,r3 jsr pc,outw 2: mov $1,r3 mov $jmp+37,r2 jsr pc,outw mov (sp)+,r3 mov (sp)+,r2 jsr pc,outw rts pc /sob opl31: / sob jsr pc,expres jsr pc,checkreg swab r2 asr r2 asr r2 bis r2,(sp) jsr pc,readop jsr pc,expres tstb passno beq 3f sub dot,r2 neg r2 mov r2,r0 jsr r5,betwen; -2; 175 br 2f add $4,r2 br 1f /branch opl6: jsr pc,expres tstb passno beq 3f dobranch: sub dot,r2 mov r2,r0 jsr r5,betwen; -254.; 256. br 2f 1: bit $1,r2 bne 2f cmp r3,dot-2 / same relocation as . bne 2f asr r2 dec r2 bic $177400,r2 3: bis (sp)+,r2 clr r3 jsr pc,outw rts pc 2: jsr r5,error; 'b clr r2 br 3b /jsr opl7: jsr pc,expres jsr pc,checkreg jmp op2a / rts opl10: jsr pc,expres jsr pc,checkreg br 1f / sys, emt etc opl11: jsr pc,expres cmp r2,$256. bhis 0f cmp r3,$1 ble 1f 0: jsr pc,errora 1: bis (sp)+,r2 jsr pc,outw rts pc / .byte opl16: jsr pc,expres jsr pc,outb cmp r4,$', bne 1f jsr pc,readop br opl16 1: tst (sp)+ rts pc / < (.ascii) opl17: jsr pc,getw mov $1,r3 mov r4,r2 bmi 2f bic $!377,r2 jsr pc,outb br opl17 2: jsr pc,getw rts pc /.even opl20: bit $1,dot beq 1f cmp dot-2,$4 beq 2f / bss mode clr r2 clr r3 jsr pc,outb br 1f 2: inc dot 1: tst (sp)+ rts pc opl21: /if jsr pc,expres opl22: oplret: tst (sp)+ rts pc /.globl opl23: cmp r4,$200 blo 1f bisb $40,(r4) jsr pc,readop cmp r4,$', bne 1f jsr pc,readop br opl23 1: tst (sp)+ rts pc / .text, .data, .bss opl25: opl26: opl27: inc dot bic $1,dot mov r0,-(sp) mov dot-2,r1 asl r1 mov dot,savdot-4(r1) tstb passno beq 1f jsr r5,flush; txtp jsr r5,flush; relp mov (sp),r2 add $txtseek-[2*25],r2 mov r2,tseekp mov (r2),r0 jsr r5,oset; txtp add $trelseek-txtseek,r2 mov (r2),r0 mov r2,rseekp jsr r5,oset; relp 1: mov (sp)+,r0 mov savdot-[2*25](r0),dot asr r0 sub $25-2,r0 mov r0,dot-2 / new . relocation tst (sp)+ rts pc opl32: cmp r4,$200 blo 1f mov r4,-(sp) jsr pc,readop jsr pc,readop jsr pc,expres mov (sp)+,r0 bit $37,(r0) bne 1f bis $40,(r0) mov r2,2(r0) 1: tst (sp)+ rts pc addres: clr -(sp) 4: cmp r4,$'( beq alp cmp r4,$'- beq amin cmp r4,$'$ beq adoll cmp r4,$'* bne getx jmp astar getx: jsr pc,expres cmp r4,$'( bne 2f jsr pc,readop mov r2,(r5)+ mov r3,(r5)+ mov xsymbol,(r5)+ jsr pc,expres jsr pc,checkreg jsr pc,checkrp bis $60,r2 bis (sp)+,r2 rts pc 2: cmp r3,$24 bne 1f jsr pc,checkreg bis (sp)+,r2 rts pc 1: mov r3,-(sp) bic $40,r3 mov (sp)+,r3 bis $100000,r3 sub dot,r2 sub $4,r2 cmp r5,$adrbuf beq 1f sub $2,r2 1: mov r2,(r5)+ / index mov r3,(r5)+ / index reloc. mov xsymbol,(r5)+ / index global mov $67,r2 / address mode bis (sp)+,r2 rts pc alp: jsr pc,readop jsr pc,expres jsr pc,checkrp jsr pc,checkreg cmp r4,$'+ beq 1f tst (sp)+ beq 2f bis $70,r2 clr (r5)+ clr (r5)+ mov xsymbol,(r5)+ rts pc 2: bis $10,r2 rts pc 1: jsr pc,readop bis $20,r2 bis (sp)+,r2 rts pc amin: jsr pc,readop cmp r4,$'( beq 1f mov r4,savop mov $'-,r4 br getx 1: jsr pc,readop jsr pc,expres jsr pc,checkrp jsr pc,checkreg bis (sp)+,r2 bis $40,r2 rts pc adoll: jsr pc,readop jsr pc,expres mov r2,(r5)+ mov r3,(r5)+ mov xsymbol,(r5)+ mov (sp)+,r2 bis $27,r2 rts pc astar: tst (sp) beq 1f jsr r5,error; '* 1: mov $10,(sp) jsr pc,readop jmp 4b errora: jsr r5,error; 'a rts pc checkreg: cmp r2,$7 bhi 1f cmp r1,$1 blos 2f cmp r3,$5 blo 1f 2: rts pc 1: jsr pc,errora clr r2 clr r3 rts pc errore: jsr r5,error; 'e rts pc checkrp: cmp r4,$') beq 1f jsr r5,error; ') rts pc 1: jsr pc,readop rts pc setbr: mov brtabp,r1 cmp r1,$brlen blt 1f mov $2,r2 rts pc 1: inc brtabp clr -(sp) sub dot,r0 ble 1f sub brdelt,r0 1: jsr r5,betwen; -254.; 256. br 1f br 2f 1: mov r1,-(sp) bic $!7,(sp) mov $1,r0 ash (sp)+,r0 ash $-3,r1 bisb r0,brtab(r1) mov $2,(sp) 2: mov (sp)+,r2 rts pc getbr: mov brtabp,r1 cmp r1,$brlen blt 1f sec rts pc 1: mov r1,-(sp) bic $!7,(sp) neg (sp) inc brtabp ash $-3,r1 movb brtab(r1),r1 ash (sp)+,r1 ror r1 / 0-bit into c-bit rts pc jsr pc,readop rts pc setbr: mov brtabp,r1 cmp r1,$brlen blt 1f mov $2,r2 rts pc 1: inc brtabp clr -(sp) sub dot,r0 ble 1f sub/ / / a7 -- pdp-11 assembler expres: clr xsymbol expres1: mov r5,-(sp) mov $'+,-(sp) clr r2 mov $1,r3 br 1f advanc: jsr pc,readop 1: mov r4,r0 jsr r5,betwen; 0; 177 br .+4 br 7f movb (r4),r0 tst r0 bne 1f tstb passno beq 1f jsr r5,error; 'u 1: cmp r0,$40 bne 1f mov r4,xsymbol clr r1 br oprand 1: mov 2(r4),r1 br oprand 7: cmp r4,$141 blo 1f asl r4 mov curfb-[2*141](r4),r0 mov 2(r0),r1 movb (r0),r0 br oprand 1: mov $esw1,r1 1: cmp (r1)+,r4 beq 1f tst (r1)+ bne 1b tst (sp)+ mov (sp)+,r5 rts pc 1: jmp *(r1) esw1: '+; binop '-; binop '*; binop '/; binop '&; binop 037; binop 035; binop 036; binop '%; binop '[; brack '^; binop 1; exnum 2; exnum1 '!; binop 200; 0 binop: cmpb (sp),$'+ beq 1f jsr pc,errore 1: movb r4,(sp) br advanc exnum1: mov numval,r1 br 1f exnum: jsr pc,getw mov r4,r1 1: mov $1,r0 br oprand brack: mov r2,-(sp) mov r3,-(sp) jsr pc,readop jsr pc,expres1 cmp r4,$'] beq 1f jsr r5,error; '] 1: mov r3,r0 mov r2,r1 mov (sp)+,r3 mov (sp)+,r2 oprand: mov $exsw2,r5 1: cmp (sp),(r5)+ beq 1f tst (r5)+ bne 1b br eoprnd 1: jmp *(r5) exsw2: '+; exadd '-; exsub '*; exmul '/; exdiv 037; exor '&; exand 035;exlsh 036;exrsh '%; exmod '^; excmbin '!; exnot 200; 0 excmbin: mov r0,r3 br eoprnd exrsh: neg r1 beq exlsh inc r1 clc ror r2 exlsh: jsr r5,combin; relte2 als r1,r2 br eoprnd exmod: jsr r5,combin; relte2 mov r3,r0 mov r2,r3 clr r2 dvd r1,r2 mov r3,r2 mov r0,r3 br eoprnd exadd: jsr r5,combin; reltp2 add r1,r2 br eoprnd exsub: jsr r5,combin; reltm2 sub r1,r2 br eoprnd exand: jsr r5,combin; relte2 com r1 bic r1,r2 br eoprnd exor: jsr r5,combin; relte2 bis r1,r2 br eoprnd exmul: jsr r5,combin; relte2 mpy r2,r1 mov r1,r2 br eoprnd exdiv: jsr r5,combin; relte2 mov r3,r0 mov r2,r3 clr r2 dvd r1,r2 mov r0,r3 br eoprnd exnot: jsr r5,combin; relte2 com r1 add r1,r2 br eoprnd eoprnd: mov $'+,(sp) jmp advanc combin: tstb passno bne combin1 mov r0,-(sp) bis r3,(sp) bic $!40,(sp) bic $!37,r0 bic $!37,r3 cmp r0,r3 ble 1f mov r0,-(sp) mov r3,r0 mov (sp)+,r3 1: tst r0 beq 1f cmp (r5)+,$reltm2 bne 2f cmp r0,r3 bne 2f mov $1,r3 br 2f 1: tst (r5)+ clr r3 2: bis (sp)+,r3 rts r5 combin1: mov r1,-(sp) clr maxtyp jsr pc,maprel mov r0,r1 mpy $6,r1 mov r3,r0 jsr pc,maprel add (r5)+,r0 add r1,r0 movb (r0),r3 bpl 1f cmp r3,$-1 beq 2f jsr r5,error; 'r 2: mov maxtyp,r3 1: mov (sp)+,r1 rts r5 maprel: cmp r0,$40 bne 1f mov $5,r0 rts pc 1: bic $!37,r0 cmp r0,maxtyp blos 1f mov r0,maxtyp 1: cmp r0,$5 blo 1f mov $1,r0 1: rts pc X = -2 M = -1 reltp2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, 2, X, X, X, X .byte 0, 3, X, X, X, X .byte 0, 4, X, X, X, X .byte 0,40, X, X, X, X reltm2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, X, 1, X, X, X .byte 0, X, X, 1, X, X .byte 0, X, X, X, 1, X .byte 0, X, X, X, X, X relte2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X, X, X p r0,$5 blo 1f mov $1,r0 1: rts pc X = -2 M = -1 reltp2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, 2, X, X, X, X .byte 0, 3, X, X, X, X .byte 0, 4, X, X, X, X .byte 0,40, X, X, X, X reltm2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, 2, 3, 4,40 .byte 0, X, 1, X, X, X .byte 0, X, X, 1, X, X .byte 0, X, X, X, 1, X .byte 0, X, X, X, X, X relte2: .byte 0, 0, 0, 0, 0, 0 .byte 0, M, X, X, X, X .byte 0, X, X, X, X, X .byte 0, X, X, X,/ / / as8 -- PDP-11 assembler pass 2 qnl: a.out: .even .data a.outp: a.out a.tmp1: 0 a.tmp2: 0 a.tmp3: 0 tseekp: txtseek rseekp: trelseek txtmagic: br .+20 txtsiz: .=.+2 datsiz: .=.+2 bsssiz: .=.+2 symsiz: .=.+2 stksiz: .=.+2 exorig: .=.+2 .=.+2 txtseek: 20 datseek:.=.+2 .=.+2 trelseek:.=.+2 drelseek:.=.+2 .=.+2 symseek:.=.+2 .bss brlen = 1024. brtab: .=.+[brlen\/8.] brtabp: .=.+2 brdelt: .=.+2 fbbufp: .=.+2 defund: .=.+2 savdot: .=.+6 datbase:.=.+2 bssbase:.=.+2 fbfil: .=.+2 fin: .=.+2 ibufc: .=.+2 txtfil: .=.+2 symf: .=.+2 adrbuf: .=.+12. xsymbol:.=.+2 fout: .=.+2 ch: .=.+2 errflg: .=.+2 wordf: .=.+2 argb: .=.+22. line: .=.+2 savop: .=.+2 curfb: .=.+20. nxtfb: .=.+20. numval: .=.+2 maxtyp: .=.+2 relfil: .=.+2 ibufp: .=.+2 txtp: .=.+6+512. relp: .=.+6+512. swapf: .=.+2 rlimit: .=.+2 passno: .=.+2 endtable:.=.+2 usymtab:.=.+20. end: .text 1024. brtab: .=.+[brlen\/8.] brtabp: .=.+2 brdelt: .=.+2 fbbufp: .=.+2 defund: .=.+2 savdot: .=.+6 datbase:.=.+2 bssbase:.=.+2 fbfil: .=.+2 fin/ / / as9 -- PDP-11 assembler pass 2 eae = 0 .data symtab: / special variables dotrel: 02; dot:000000 /. 01; dotdot:000000 /.. / register 24;000000 /r0 24;000001 /r1 24;000002 /r2 24;000003 /r3 24;000004 /r4 24;000005 /r5 24;000006 /sp 24;000007 /pc .if eae /eae & switches 01;177570 /csw 01;177300 /div 01;177302 /ac 01;177304 /mq 01;177306 /mul 01;177310 /sc 01;177311 /sr 01;177312 /nor 01;177314 /lsh 01;177316 /ash .endif / system calls 01;0000000 /indir 01;0000001 /exit 01;0000002 /fork 01;0000003 /read 01;0000004 /write 01;0000005 /open 01;0000006 /close 01;0000007 /wait 01;0000010 /creat 01;0000011 /link 01;0000012 /unlink 01;0000013 /exec 01;0000014 /chdir 01;0000015 /time 01;0000016 /mknod 01;0000017 /chmod 01;0000020 /chown 01;0000021 /break 01;0000022 /stat 01;0000023 /seek 01;0000024 /getpid 01;0000025 /mount 01;0000026 /umount 01;0000027 /setuid 01;0000030 /getuid 01;0000031 /stime 01;0000032 /ptrace 01;0000034 /fstat 01;0000037 /stty 01;0000040 /gtty 01;0000042 /nice 01;0000043 /sleep 01;0000044 /sync 01;0000045 /kill 01;0000046 /csw 01;0000051 /dup 01;0000052 /pipe 01;0000053 /times 01;0000054 /profil 01;0000056 /setgid 01;0000057 /getgid 01;0000060 /signal / double operand 13;0010000 /mov 13;0110000 /movb 13;0020000 /cmp 13;0120000 /cmpb 13;0030000 /bit 13;0130000 /bitb 13;0040000 /bic 13;0140000 /bicb 13;0050000 /bis 13;0150000 /bisb 13;0060000 /add 13;0160000 /sub / branch 06;0000400 /br 06;0001000 /bne 06;0001400 /beq 06;0002000 /bge 06;0002400 /blt 06;0003000 /bgt 06;0003400 /ble 06;0100000 /bpl 06;0100400 /bmi 06;0101000 /bhi 06;0101400 /blos 06;0102000 /bvc 06;0102400 /bvs 06;0103000 /bhis 06;0103000 /bec 06;0103000 /bcc 06;0103400 /blo 06;0103400 /bcs 06;0103400 /bes / jump/ branch type 35;0000400 /jbr 36;0001000 /jne 36;0001400 /jeq 36;0002000 /jge 36;0002400 /jlt 36;0003000 /jgt 36;0003400 /jle 36;0100000 /jpl 36;0100400 /jmi 36;0101000 /jhi 36;0101400 /jlos 36;0102000 /jvc 36;0102400 /jvs 36;0103000 /jhis 36;0103000 /jec 36;0103000 /jcc 36;0103400 /jlo 36;0103400 /jcs 36;0103400 /jes / single operand 15;0005000 /clr 15;0105000 /clrb 15;0005100 /com 15;0105100 /comb 15;0005200 /inc 15;0105200 /incb 15;0005300 /dec 15;0105300 /decb 15;0005400 /neg 15;0105400 /negb 15;0005500 /adc 15;0105500 /adcb 15;0005600 /sbc 15;0105600 /sbcb 15;0005700 /tst 15;0105700 /tstb 15;0006000 /ror 15;0106000 /rorb 15;0006100 /rol 15;0106100 /rolb 15;0006200 /asr 15;0106200 /asrb 15;0006300 /asl 15;0106300 /aslb 15;0000100 /jmp 15;0000300 /swab / jsr 07;0004000 /jsr / rts 10;000200 /rts / simple operand 11;104400 /sys / flag-setting 01;0000241 /clc 01;0000242 /clv 01;0000244 /clz 01;0000250 /cln 01;0000261 /sec 01;0000262 /sev 01;0000264 /sez 01;0000270 /sen / floating point ops 01;170000 / cfcc 01;170001 / setf 01;170011 / setd 01;170002 / seti 01;170012 / setl 15;170400 / clrf 15;170700 / negf 15;170600 / absf 15;170500 / tstf 12;172400 / movf 14;177000 / movif 05;175400 / movfi 14;177400 / movof 05;176000 / movfo 14;172000 / addf 14;173000 / subf 14;171000 / mulf 14;174400 / divf 14;173400 / cmpf 14;171400 / modf 14;176400 / movie 05;175000 / movei 15;170100 / ldfps 15;170200 / stfps 24;000000 / fr0 24;000001 / fr1 24;000002 / fr2 24;000003 / fr3 24;000004 / fr4 24;000005 / fr5 / 11/45 operations 30;072000 /als (ash) 30;073000 /alsc (ashc) 30;070000 /mpy .if eae-1 30;070000/ mul 30;071000 / div 30;072000 / ash 30;073000 /ashc .endif 30;071000 /dvd 07;074000 /xor 15;006700 /sxt 11;006400 /mark 31;077000 /sob / specials 16;000000 /.byte 20;000000 /.even 21;000000 /.if 22;000000 /.endif 23;000000 /.globl 25;000000 /.text 26;000000 /.data 27;000000 /.bss 32;000000 /.comm start: mov (sp)+,r0 tst (sp)+ 1: mov (sp)+,r1 cmpb (r1),$'- bne 1f dec r0 cmpb 1(r1),$'g bne 2f mov $40,defund / globalize externals br 1b 2: cmpb 1(r1),$'o bne 1b dec r0 mov (sp)+,r1 mov r1,a.outp mov r1,a.outp1 mov r1,a.outp2 br 1b 1: cmp r0,$4 bge 1f jmp aexit 1: mov r1,a.tmp1 mov (sp)+,a.tmp2 mov (sp)+,a.tmp3 jsr r5,ofile; a.tmp1 movb r0,txtfil jsr r5,ofile; a.tmp2 movb r0,fbfil jsr r5,ofile; a.tmp3 movb r0,symf movb r0,fin sys creat; a.outp1:a.out; 0 bec 1f jsr r5,filerr; a.outp 1: movb r0,fout jmp go / overlaid buffer inbuf = start . = inbuf+512. b 1(r1),$'g bne 2f mov $40,defund / globalize externals br 1b 2: cmpb 1(r1),$'o bne 1b dec r0 mov (sp)+,r1 mov r1,a.outp mov r1,a.outp1 mov r1,a.outp2 br 1b 1: cmp r0,$4 bge 1f jmp aexit 1: mov r1,a.tmp1 mov (sp)+,a.tmp2 mov (sp)+,a.tmp3 jsr r5,ofile; a.tmp1 movb r0,txtfil jsr r5,ofile; a.tmp2 movb r0,fbfil jsr r5,ldfps = 170100^tst stfps = 170200^tst / .globl atan, _atan .globl atan2, _atan2 / / floating-point arctangent / / atan replaces the value in fr0 by its arctangent / in the range [-pi/2,pi/2]. / / atan2 places in fr0 the arctangent of fr0/fr1 / in the range [-pi,pi]. / / there are no error exits / / coefficients are #5076 from Hart & Cheney. / / _atan: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,atan br 1f _atan2: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 movf 12.(r5),fr1 jsr pc,atan2 1: mov (sp)+,r5 rts pc atan: jsr r0,save tstf fr0 cfcc blt 1f jsr pc,satan br ret 1: negf fr0 jsr pc,satan negf fr0 br ret / atan2: jsr r0,save clr -(sp) tstf fr0 cfcc bge 1f inc (sp) negf fr0 1: tstf fr1 cfcc beq 2f bgt 1f add $2,(sp) negf fr1 1: divf fr1,fr0 jsr pc,satan br 1f 2: movf pi2,fr0 1: bit $2,(sp) beq 1f negf fr0 addf pi2,fr0 addf pi2,fr0 1: bit $1,(sp)+ beq 1f negf fr0 1: ret: ldfps (sp)+ movf (sp)+,fr3 movf (sp)+,fr2 movf (sp)+,fr1 mov (sp)+,r0 rts pc save: movf fr1,-(sp) movf fr2,-(sp) movf fr3,-(sp) stfps -(sp) ldfps $40200 / DP, no interrupt jmp (r0) satan: cmpf sq2m1,fr0 cfcc bge arctan cmpf sq2p1,fr0 cfcc bgt 1f movf one,fr1 divf fr0,fr1 movf fr1,fr0 jsr pc,arctan negf fr0 addf pi2,fr0 rts pc 1: movf fr0,fr1 subf one,fr0 addf one,fr1 divf fr1,fr0 jsr pc,arctan addf pi4,fr0 rts pc arctan: mov $p4p,r0 mov $4,-(sp) movf fr0,fr3 mulf fr3,fr3 movf *(r0)+,fr1 1: mulf fr3,fr1 addf *(r0)+,fr1 dec (sp) bne 1b mov $4,(sp) movf fr3,fr2 br 2f 1: mulf fr3,fr2 2: addf *(r0)+,fr2 dec (sp) bne 1b tst (sp)+ divf fr2,fr1 mulf fr1,fr0 rts pc .data p4p: p4;p3;p2;p1;p0 q3;q2;q1;p0 one: 40200;0;0;0 pi2: 40311;7732;121041;64302 pi4: 40111;7732;121041;64302 sq2p1: 40432 101171 114774 167461 sq2m1: 37724 11714 147747 74621 p4: 37442 145026 75504 15621 p3: 40725 21566 115517 50305 p2: 41443 160206 172714 25441 p1: 41632 172223 76027 56645 p0: 41462 25125 6152 126064 q3: 41170 10112 141724 64324 q2: 41573 53776 25372 71522 q1: 41670 123114 51576 75020 / one = 1.00000 00000 00000 00000 d0 / sq2p1=2.41421 35623 73095 04880 d0 / sq2m1= .41421 35623 73095 04880 d0 / pi2 = 1.57079 63267 94896 61923 d0 / p4 = .15897 40288 48230 7048 d0 / p3 = .66605 79017 00926 2658 d1 / p2 = .40969 26483 21022 5637 d2 / p1 = .77477 68771 92042 0862 d2 / p0 = .44541 34005 92906 8032 d2 / q4 = .10000 00000 00000 0000 d1 / q3 = .15503 97755 14219 8753 d2 / q2 = .62835 93051 10323 7683 d2 / q1 = .92324 80107 23009 7484 d2 / q0 = .44541 34005 92906 8044 d2 123114 51576 75020 / one = 1.00000 00000 00000 00000 d0 / sq2p1=2.41421 35623 73095 04880 d0 / sq2m1= .41421 35623 73095 04880 d0 / pi2 = 1.57079 63267 94896 61923 d0 / p4 = .15897 40288 48230 7048 d0 / p3 = .66605 79017 00926 2658 d1 / p2 = .40969 26483 21022 5637 d2 / p1 = .77477 68771 92042 0862 d2 / p0 = .44541 34005 92906 8032 d2 / q4 = .10000 00000 00000 0000 d1 / q3 = .15503 97755 14219 8753 d2 / q2 = .62835 93051 10323 7683 d2 / q1 = .92324 80107 23009 7484 d2 / q0 = ldfps = 170100^tst stfps = 170200^tst / .globl atof .globl atoi / / atof - ascii to floating (input) conversion / uses klt's ghastly calling convention / result is returned in fr0 / / atof: stfps -(sp) ldfps $200 movf fr1,-(sp) mov r1,-(sp) mov r2,-(sp) / clr -(sp) clrf fr0 clr r2 jsr r5,*(r5) cmpb r0,$'- bne 2f inc (sp) 1: jsr r5,*(r5) 2: sub $'0,r0 cmp r0,$9. bhi 2f jsr pc,digit br 1b inc r2 br 1b 2: cmpb r0,$'.-'0 bne 2f 1: jsr r5,*(r5) sub $'0,r0 cmp r0,$9. bhi 2f jsr pc,digit dec r2 br 1b 2: cmpb r0,$'e-'0 bne 1f mov (r5),0f jsr r5,atoi; 0:.. sub $'0,r0 add r1,r2 1: movf $one,fr1 mov r2,-(sp) beq 2f bgt 1f neg r2 1: cmp r2,$38. blos 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: mulf fr1,fr0 cfcc bvc 2f movf $huge,fr0 2: out: tst (sp)+ beq 1f negf fr0 1: add $'0,r0 mov (sp)+,r2 mov (sp)+,r1 movf (sp)+,fr1 ldfps (sp)+ tst (r5)+ rts r5 / / digit: cmpf $big,fr0 cfcc blt 1f mulf $ten,fr0 movif r0,fr1 addf fr1,fr0 rts pc 1: add $2,(sp) rts pc / / one = 40200 ten = 41040 big = 56200 huge = 77777 f bgt 1f neg r2 1: cmp r2,$38. blos 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: mulf fr1,fr0 cfcc bvc 2f movf $huge,fr0 2: out: tst (sp)+ beq 1f negf fr0 1: add $'0,r0 mov (sp)+,r2 mov (sp)+,r1 movf (sp)+,fr1 ldfps (sp)+ tst (r5)+ rts r5 / / digit: cmpf $big,fr0 cfc/ atoi / ascii to integer input conversion / jsr r5,atoi; getc .globl atoi atoi: clr r1 jsr r5,*(r5) clr -(sp) cmp r0,$'- bne 2f inc (sp) 1: jsr r5,*(r5) 2: sub $'0,r0 cmp r0,$9 bhi 1f mpy $10.,r1 add r0,r1 br 1b 1: add $'0,r0 tst (sp)+ beq 1f neg r1 1: tst (r5)+ rts r5 1,fr0 br 2f 1: mulf fr1,fr0 cfcc bvc 2f movf $huge,fr0 2: out: tst (sp)+ beq 1f negf fr0 1: add $'0,r0 mov (sp)+,r2 mov (sp)+,r1 movf (sp)+,fr1 ldfps (sp)+ tst (r5)+ rts r5 / / digit: cmpf $big,fr0 cfc/ default comparison routine for qsort / set codes for / / cmp (r0),(r4) / .globl compare compare: mov r3,-(sp) mov r4,-(sp) 1: cmpb (r0)+,(r4)+ bne 1f dec r3 bne 1b clr r0 br 2f 1: blo 1f mov $1,r0 br 2f 1: mov $-1,r0 2: mov (sp)+,r4 mov (sp)+,r3 tst r0 rts pc )+ rts r5 1,fr0 br 2f 1: mulf fr1,fr0 cfcc bvc 2f movf $huge,fr0 2: out: tst (sp)+ beq 1f negf fr0 1: add $'0,r0 mov (sp)+,r2 mov (sp)+,r1 movf (sp)+,fr1 ldfps (sp)+ tst (r5)+ rts r5 / / digit: cmpf $big,fr0 cfc/ crypt -- password incoding / mov $key,r0 / jsr pc,crypt .globl crypt, _crypt .globl savr5 _crypt: mov r5,-(sp) mov sp,r5 mov r5,savr5 mov 4(r5),r0 jsr pc,crypt clr savr5 mov (sp)+,r5 rts pc crypt: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) mov r5,-(sp) mov r0,r1 mov $key,r0 movb $004,(r0)+ movb $034,(r0)+ 1: cmp r0,$key+64. bhis 1f movb (r1)+,(r0)+ bne 1b 1: dec r0 / / / fill out key space with clever junk / mov $key,r1 1: movb -1(r0),r2 movb (r1)+,r3 xor r3,r2 movb r2,(r0)+ cmp r0,$key+128. blo 1b / / / establish wheel codes and cage codes / mov $wheelcode,r4 mov $cagecode,r5 mov $256.,-(sp) 2: clr r2 clr (r4) mov $wheeldiv,r3 3: clr r0 mov (sp),r1 div (r3)+,r0 add r1,r2 bic $40,r2 bis shift(r2),(r4) cmp r3,$wheeldiv+6. bhis 4f bis shift+4(r2),(r5) 4: cmp r3,$wheeldiv+10. blo 3b sub $2,(sp) tst (r4)+ tst (r5)+ cmp r4,$wheelcode+256. blo 2b tst (sp)+ / .data shift: 1;2;4;10;20;40;100;200;400;1000;2000;4000;10000;20000;40000;100000 1;2 wheeldiv: 32.; 18.; 10.; 6.; 4. .bss cagecode: .=.+256. wheelcode: .=.+256. .text / / / make the internal settings of the machine / both the lugs on the 128 cage bars and the lugs / on the 16 wheels are set from the expanded key / mov $key,r0 mov $cage,r2 mov $wheel,r3 1: movb (r0)+,r1 bic $!177,r1 asl r1 mov cagecode(r1),(r2)+ mov wheelcode(r1),(r3)+ cmp r0,$key+128. blo 1b / / / now spin the cage against the wheel to produce output. / mov $word,r4 mov $wheel+128.,r3 3: mov -(r3),r2 mov $cage,r0 clr r5 1: bit r2,(r0)+ beq 2f incb r5 2: cmp r0,$cage+256. blo 1b / / we have a piece of output from current wheel / it needs to be folded to remove lingering hopes of / inverting the function / mov r4,-(sp) clr r4 div $26.+26.+10.,r4 add $'0,r5 cmp r5,$'9 blos 1f add $'A-'9-1,r5 cmp r5,$'Z blos 1f add $'a-'Z-1,r5 1: mov (sp)+,r4 movb r5,(r4)+ cmp r4,$word+8. blo 3b / mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov $word,r0 rts pc .bss key: .=.+128. word: .=.+32. cage: .=.+256. wheel: .=.+256. cb r5 2: cmp r0,$cage+256. blo 1b / / we have a piece of output from current wheel / it needs to be folded to remove lingering hopes of / inverting the function / mov r4,-(sp) clr r4 div $26.+26.+10.,r4 add $'0,r5 cmp r5,$'9 blos 1f add $'A-'9-1,r5 cmp r5,$'Z blos 1f add $'a-'Z-1,r5 1: mov (sp)+,r4 movb r5,(r4)+ cmp r4,$word+8. blo 3b / mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov $word,r0 rts pc .bss key: .=.+128. word: .=.+3/ C library -- signed dp add .globl _dpadd _dpadd: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 tst 6(r5) sxt r1 add r1,(r0)+ add 6(r5),(r0) adc -(r0) mov (sp)+,r5 rts pc inverting the function / mov r4,-(sp) clr r4 div $26.+26.+10.,r4 add $'0,r5 cmp r5,$'9 blos 1f add $'A-'9-1,r5 cmp r5,$'Z blos 1f add $'a-'Z-1,r5 1: mov (sp)+,r4 movb r5,(r4)+ cmp r4,$word+8. blo 3b / mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov $word,r0 rts pc .bss key: .=.+128. word: .=.+3ldfps = 170100^tst stfps = 170200^tst / ftoa -- basic g fp conversion .globl _ndigit .globl ecvt .globl fcvt / ecvt converts fr0 into decimal / the string of converted digits is pointed to by r0. / the number of digits are specified by _ndigit / r2 contains the decimal point / r1 contains the sign .globl _ecvt, _fcvt _ecvt: mov r5,-(sp) mov sp,r5 mov r2,-(sp) movf 4(r5),fr0 mov 14(r5),_ndigit jsr pc,ecvt br 1f _fcvt: mov r5,-(sp) mov sp,r5 mov r2,-(sp) movf 4(r5),fr0 mov 14(r5),_ndigit jsr pc,fcvt 1: mov r2,*16(r5) mov r1,*20(r5) mov (sp)+,r2 mov (sp)+,r5 rts pc fcvt: clr eflag br 1f ecvt: mov $1,eflag 1: stfps -(sp) ldfps $200 movf fr0,-(sp) movf fr1,-(sp) mov r3,-(sp) mov $buf,r1 clr r2 clr sign tstf fr0 cfcc beq zer bgt 1f inc sign negf fr0 1: modf $one,fr0 tstf fr1 cfcc beq lss gtr: movf fr0,-(sp) movf fr1,fr0 1: mov $buftop,r3 1: modf tenth,fr0 movf fr0,fr2 movf fr1,fr0 addf $epsilon,fr2 modf $ten,fr2 movfi fr3,r0 add $'0,r0 movb r0,-(r3) inc r2  tstf fr0 cfcc bne 1b / mov $buf,r1 1: movb (r3)+,(r1)+ cmp r3,$buftop blo 1b / movf (sp)+,fr0 br pad zer: inc r2 br pad lss: dec r2 modf $ten,fr0 tstf fr1 cfcc beq lss inc r2 jsr pc,digit1 pad: jsr pc,digit br out br pad digit: cmp r1,$buftop bhis 1f add $2,(sp) modf $ten,fr0 digit1: movfi fr1,r0 add $'0,r0 movb r0,(r1)+ 1: rts pc / out: mov $buf,r0 add _ndigit,r0 tst eflag bne 1f add r2,r0 1: cmp r0,$buf blo outout movb (r0),r3 add $5,r3 movb r3,(r0) 1: cmpb (r0),$'9 ble 1f movb $'0,(r0) cmp r0,$buf blos 2f incb -(r0) br 1b 2: movb $'1,(r0) inc r2 1: outout: mov sign,r1 mov _ndigit,r0 tst eflag bne 1f add r2,r0 1: clrb buf(r0) mov $buf,r0 mov (sp)+,r3 movf (sp)+,fr1 movf (sp)+,fr0 ldfps (sp)+ rts pc epsilon = 037114 one = 40200 ten = 41040 .data tenth: 037314; 146314; 146314; 146315 _ndigit:10. .bss buf: .=.+60. buftop: sign: .=.+2 eflag: .=.+2 .text add r2,r0 1: cmp r0,$buf blo outout movb (r0),r3 add $5,r3 movb r3,(r0) 1: cmpb (r.globl exp, _exp / ldfps = 170100^tst stfps = 170200^tst ldexp = 176400^movif stexp = 175000^movfi / / exp accepts its argument and returns its result / in fr0. The carry bit is set if the result overflows. / The coefficients are #1067 from Hart & Cheney. / / movf arg,fr0 / jsr pc,exp / movf fr0,result / _exp: mov r5,-(sp) mov sp,r5 mov 4(r5),fr0 jsr pc,exp mov (sp)+,r5 rts pc exp: stfps -(sp) ldfps $200 /di mode movf fr2,-(sp) movf fr1,-(sp) tstf fr0 cfcc bne 1f movf $one,fr0 /exp(0) clc  br out 1: modf log2e,fr0 /exp(x) = 2^(x*log2(e)) cfcc bmi 2f movfi fr1,-(sp) /save integer part subf $half,fr0 br 3f 2: movfi fr1,-(sp) dec (sp) addf $half,fr0 3: movf fr0,fr1 / -.5 < x < +.5 mulf fr1,fr1 /arg**2 / movf P2,fr2 mulf fr1,fr2 addf P1,fr2 mulf fr1,fr2 addf P0,fr2 mulf fr2,fr0 /xP(x**2) / movf fr1,fr2 addf Q1,fr2 mulf fr1,fr2 addf Q0,fr2 /Q(x**2) / movf fr2,fr1 subf fr0,fr1 addf fr2,fr0 divf fr1,fr0 /(Q+xP)/(Q-xP) mulf sqrt2,fr0 / stexp fr0,-(sp) add (sp)+,(sp) / cmp (sp),$177 ble 2f tst (sp)+ movf big,fr0 /overflow sec br 1f 2: cmp (sp),$-177 bge 2f tst (sp)+ clrf fr0 /underflow clc br 1f 2: ldexp (sp)+,fr0 clc 1: out: movf (sp)+,fr1 movf (sp)+,fr2 ldfps (sp)+ rts pc / / .data P0: 42675; 36404; 77563; 46675 P1: 41241; 116724; 114237; 60333 P2: 36675; 27102; 125560; 136652 Q0: 43210; 100661; 76072; 62453 Q1: 42151; 27450; 75350; 112503 log2e: 40270; 125073; 24534; 13761 sqrt2: 40265; 02363; 31771; 157144 half = 40000 one = 40200 / big: 77777; 177777; 177777; 177777 / / P0 = .15139 06799 05433 89158 94328 d4 / P1 = .20202 06565 12869 27227 886 d2 / P2 = .23093 34775 37502 33624 d-1 / / Q0 = .43682 11662 72755 84984 96814 d4 / Q1 = .23318 42114 27481 62379 0295 d3 / Q2 = .1 d1 / / log2e = 1.44269 50408 88963 40735 99246 / sqrt2 = 1.41421 35623 73095 04880 16887 Q1: 42151; 27450; 75350; 112503 log2e: 40270; 125073; 24534; 13761 sqrt2: 40265; 02363; 31771; 157144 half = 40000 one = .globl _floor, _ceil .globl floor, ceil one = 40200 _floor: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,floor br 1f _ceil: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,ceil 1: mov (sp)+,r5 rts pc floor: tstf fr0 cfcc bge 1f modf $one,fr0 cfcc beq 2f subf $one,fr1 br 2f 1: modf $one,fr0 2: movf fr1,fr0 rts pc ceil: negf fr0 jsr pc,floor negf fr0 rts pc 42151; 27450; 75350; 112503 log2e: 40270; 125073; 24534; 13761 sqrt2: 40265; 02363; 31771; 157144 half = 40000 one = / C floating mod / fmod(a,b) returns a number n such that / i*b + n is a and 0 <= n < b .globl _fmod _fmod: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 divf 12.(r5),fr0 modf $one,fr0 mulf 12.(r5),fr1 movf 4(r5),fr0 subf fr1,fr0 mov (sp)+,r5 rts pc one = 40200 eq 2f subf $one,fr1 br 2f 1: modf $one,fr0 2: movf fr1,fr0 rts pc ceil: negf fr0 jsr pc,floor negf fr0 rts pc 42151; 27450; 75350; 112503 log2e: 40270; 125073; 24534; 13761 sqrt2: 40265; 02363; 31771; 157144 half = 40000 one = .globl gamma, _gamma, signgam, _signgam .globl log, sin half = 040000 one = 40200 two = 40400 eight = 41000 large = 77777 ldfps = 170100^tst stfps = 170200^tst / / gamma computes the log of the abs of the gamma function. / gamma accepts its argument and returns its result / in fr0. The carry bit is set if the result is / too large to represent. / The sign of the gamma function is / returned in the globl cell signgam. / / The coefficients for expansion around zero / are #5243 from Hart & Cheney; for expansion / around infinity they are #5404. / / movf arg,fr0 / jsr pc,gamma / movf fr0,... / _gamma: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,gamma mov (sp)+,r5 rts pc gamma: stfps -(sp) ldfps $200 clr signgam movf fr1,-(sp) tstf fr0 cfcc ble negative cmpf $eight,fr0 cfcc blt asymptotic jsr pc,regular / lret: jsr pc,log bec ret 4 ret: movf (sp)+,fr1 ldfps (sp)+ clc rts pc / erret: movf $large,fr0 movf (sp)+,fr1 ldfps (sp)+ sec rts pc / / here for positive x > 8 / the log of the gamma function is / approximated directly by the asymptotic series. / asymptotic: movf fr0,-(sp) movf fr0,fr1 jsr pc,log subf $half,fr1 mulf fr1,fr0 subf (sp),fr0 addf goobie,fr0 / movf $one,fr1 divf (sp)+,fr1 movf fr0,-(sp) movf fr1,-(sp) mulf fr1,fr1 / mov r0,-(sp) mov $p5p,r0 mov $5,-(sp) movf *(r0)+,fr0 1: mulf fr1,fr0 addf *(r0)+,fr0 dec (sp) bne 1b tst (sp)+ mov (sp)+,r0 mulf (sp)+,fr0 addf (sp)+,fr0 br ret / / here on negative / the negative gamma is computed / in terms of the pos gamma. / negative: absf fr0 movf fr0,fr1 mulf pi,fr0 jsr pc,sin negf fr0 cfcc beq erret bgt 1f inc signgam absf fr0 1: mov signgam,-(sp) mulf fr1,fr0 divf pi,fr0 jsr pc,log movf fr0,-(sp) movf fr1,fr0 jsr pc,gamma addf (sp)+,fr0 negf fr0 mov (sp)+,signgam br ret / / control comes here for arguments less than 8. / if the argument is 23 then the argument / is reduced in range by the formula / gamma(x+1) = x*gamma(x) / regular: subf $two,fr0 cfcc bge 1f addf $two,fr0 movf fr0,-(sp) addf $one,fr0 movf fr0,-(sp) addf $one,fr0 jsr pc,regular divf (sp)+,fr0 divf (sp)+,fr0 rts pc 1: cmpf $one,fr0 cfcc bgt 1f addf $one,fr0 movf fr0,-(sp) subf $two,fr0 jsr pc,1b mulf (sp)+,fr0 rts pc 1: movf fr2,-(sp) mov r0,-(sp) mov $p4p,r0 mov $6,-(sp) movf fr0,fr2 movf *(r0)+,fr0 1: mulf fr2,fr0 addf *(r0)+,fr0 dec (sp) bne 1b mov $7,(sp) movf fr2,fr1 br 2f 1: mulf fr2,fr1 2: addf *(r0)+,fr1 dec (sp) bne 1b tst (sp)+ mov (sp)+,r0 divf fr1,fr0 movf (sp)+,fr2 rts pc / .data p4p: p6;p5;p4;p3;p2;p1;p0 q6;q5;q4;q3;q2;q1;q0 / p6 = -.67449 50724 59252 89918 d1 / p5 = -.50108 69375 29709 53015 d2 / p4 = -.43933 04440 60025 67613 d3 / p3 = -.20085 27401 30727 91214 d4 / p2 = -.87627 10297 85214 89560 d4 / p1 = -.20886 86178 92698 87364 d5 / p0 = -.42353 68950 97440 89647 d5 / q7 = 1.0 d0 / q6 = -.23081 55152 45801 24562 d2 / q5 = +.18949 82341 57028 01641 d3 / q4 = -.49902 85266 21439 04834 d3 / q3 = -.15286 07273 77952 20248 d4 / q2 = +.99403 07415 08277 09015 d4 / q1 = -.29803 85330 92566 49932 d4 / q0 = -.42353 68950 97440 90010 d5 p1: 143643 26671 36161 72154 p2: 143410 165327 54121 172630 p3: 142773 10340 74264 152066 p4: 142333 125113 176657 75740 p5: 141510 67515 65111 24263 p6: 140727 153242 163350 32217 p0: 144045 70660 101665 164444 q1: 143072 43052 50302 136745 q2: 43433 50472 145404 175462 q3: 142677 11556 144553 154177 q4: 142371 101646 141245 11264 q5:  42075 77614 43022 27573 q6: 141270 123404 76130 12650 q0: 144045 70660 101665 164444 p5p: s5;s4;s3;s2;s1;s0 / / s5 = -.16334 36431 d-2 / s4 = +.83645 87892 2 d-3 / s3 = -.59518 96861 197 d-3 / s2 = +.79365 05764 93454 d-3 / s1 = -.27777 77777 35865 004 d-2 / s0 = +.83333 33333 33331 01837 d-1 / goobie = 0.91893 85332 04672 74178 d0 s5: 135726 14410 15074 17706 s4: 35533 42714 111634 76770 s3: 135434 3200 171173 156141 s2: 35520 6375 12373 111437 s1: 136066 5540 132625 63540 s0: 37252 125252 125252 125047 goobie: 40153 37616 41445 172645 pi: 40511 7732 121041 64302 .bss _signgam: signgam:.=.+2 6334 36431 d-2 / s4 = +.83645 87892 2 d-3 / s3 = -.59518 96861 197 d-3 / s2 = +.79365 05764 93454 d-3 / s1 = -.27777 77777 35865 004 d-2 / s0 = +.83333 33333 33331 01837 d-1 / goobie = 0.91893 85332 04672 74178 d0 s5: 135726 14410 15074 17706 s4: 35533 42714 111634 76770 s3: 135434 3200 171173 156141 s2: 35520 6375 12373 111437 s1: 136066 5540 132625 63540/ getw/getc -- get words/characters from input file / fopen -- open a file for use by get(c|w) / / calling sequences -- / / mov $filename,r0 / jsr r5,fopen; ioptr / / on return ioptr buffer is set up or error bit is set if / file could not be opened. / / jsr r5,get(c|w)1; ioptr / / on return char/word is in r0; error bit is / set on error or end of file. / / ioptr is the address of a 518-byte buffer / whose layout is as follows: / / ioptr: .=.+2 / file descriptor / .=.+2 / charact+2 / pointer to next character (reset if no. chars=0) / .=.+512. / the buffer .globl getc,getw,fopen fopen: mov r1,-(sp) mov (r5)+,r1 mov r0,0f sys 0; 9f .data 9: sys open; 0:..; 0 .text bes 1f mov r0,(r1)+ clr (r1)+ mov (sp)+,r1 rts r5 1: mov $-1,(r1) mov (sp)+,r1 sec rts r5 .data getw: mov (r5),9f mov (r5)+,8f jsr r5,getc; 8:.. bec 1f rts r5 1: mov r0,-(sp) jsr r5,getc; 9:.. swab r0 bis (sp)+,r0 rts r5 .text getc: mov r1,-(sp) mov (r5)+,r1 dec 2(r1) bge 1f mov r1,r0 add $6,r0 mov r0,0f mov r0,4(r1) mov (r1),r0 sys 0; 9f .data 9: sys read; 0:..; 512. .text bes 2f tst r0 bne 3f 2: mov (sp)+,r1 sec rts r5 3: dec r0 mov r0,2(r1) 1: clr r0 bisb *4(r1),r0 inc 4(r1) mov (sp)+,r1 rts r5 (sp)+,r1 rts r5 1: mov $-1,(r1) mov (sp)+,r1 sec rts r5 .data getw: mov (r5),9f mov (r5)+,8f jsr r5,getc; 8:.. bec 1f rts r5 1: mov r0,-(sp) jsr r5,getc; 9:.. swab r0 bis (sp)+,r0 rts r5 .text getc: mov r1,-(sp) mov (r5)+,r1 dec 2(r1) bge 1f mov / hypot -- sqrt(fr0**2 + fr1**2) -> fr0; no overflow unless / necessary. / c-bit is set on overflow .globl hypot .globl sqrt hypot: movf fr1,-(sp) absf fr0 absf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr r5,sqrt mulf fr1,fr0 cfcc movf (sp)+,fr1 rts r5 one = 40200 jsr r5,getc; 9:.. swab r0 bis (sp)+,r0 rts r5 .text getc: mov r1,-(sp) mov (r5)+,r1 dec 2(r1) bge 1f mov / C library-- long divide/remainder .globl _ldiv, _ldivr .globl _lrem _ldiv: mov 2(sp),r0 mov 4(sp),r1 div 6(sp),r0 mov r1,_ldivr rts pc _lrem: mov 2(sp),r0 mov 4(sp),r1 div 6(sp),r0 mov r1,r0 rts pc .bss _ldivr: .=.+2 ovf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr r5,sqrt mulf fr1,fr0 cfcc movf (sp)+,fr1 rts r5 one = 40200 jsr r5,getc; 9:.. swab r0 bis (sp)+,r0 rts r5 .text getc: mov r1,-(sp) mov (r5)+,r1 dec 2(r1) bge 1f mov .globl log, _log ldfps = 170100^tst stfps = 170200^tst ldexp = 176400^movif stexp = 175000^movfi / / log accepts its argument and returns its result / in fr0. The carry bit is set if the argument is / zero or negative. / The coefficients are #2705 from Hart & Cheney. / / movf arg,fr0 / jsr pc,log / movf fr0,... / _log: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,log mov (sp)+,r5 rts pc log: tstf fr0 cfcc bgt 1f movf $bigneg,fr0 /return -(big) on error sec rts pc 1: stfps -(sp) ldfps $200 /di mode movf fr2,-(sp) movf fr1,-(sp) / stexp fr0,-(sp) /scale ldexp $0,fr0 cmpf sqrt2o2,fr0 cfcc blt 1f ldexp $1,fr0 dec (sp) 1: movf fr0,fr1 /(1/2)^(1/2) < x < 2^(1/2) subf $one,fr0 addf $one,fr1 divf fr1,fr0 /z = (x-1)/(x+1) movf fr0,fr1 mulf fr0,fr1 /z^2 / movf p3,fr2 mulf fr1,fr2 addf p2,fr2 mulf fr1,fr2 addf p1,fr2 mulf fr1,fr2 addf p0,fr2 mulf fr2,fr0 /zP(z) / movf fr1,fr2 addf q2,fr2 mulf fr1,fr2 addf q1,fr2 mulf fr1,fr2 addf q0,fr2 /Q(z) / divf fr2,fr0 /zP(z)/Q(z) movif (sp)+,fr1 mulf log2,fr1 addf fr1,fr0 / movf (sp)+,fr1 movf (sp)+,fr2 ldfps (sp)+ rts pc / / one = 40200 bigneg = 177777 / .data sqrt2o2: 40065; 02363; 31771; 157145 log2: 40061; 71027;173721;147572 / p0: 141300; 16201; 02154; 10216 p1: 41367;124211; 21611;114442 p2: 141032; 31773; 64222; 40261 p3: 37727;114303;110107;114145 / q0: 141100; 16201; 02154; 10216 q1: 41233;154404;136454; 22153 q2: 141016;111747; 07541; 52530 / / /p0 = -.24013 91795 59210 50986 8484 d2 /p1 = .30957 29282 15376 50062 264 d2 /p2 = -.96376 90933 68686 59324 d1 /p3 = .42108 73712 17979 7145 d0 / /q0 = -.12006 95897 79605 25471 7525 d2 /q1 = .19480 96607 00889 73051 623 d2 /q2 = -.89111 09027 93783 12337 d1 /q3 = .1 d1 / 21611;114442 p2: 141032; 31773; 64222; 40261 p3: 37727;114303;110107;114145 / q0: 141100; 16201; 02154; 10216 q1: 41233;154404;136454; 22153 q2: 141016;111747; 07541; 52530 / / /p0 = -.24013 91795 59210 50986 8484 d2 /p1 = .30957 29282 15376.globl mesg / usage: / jsr r5,mesg / / .even / ... / / string is output onto $1 / mesg: mov r0,-(sp) mov r5,r0 mov r5,0f 1: tstb (r5)+ bne 1b sub r5,r0 com r0 mov r0,0f+2 mov $1,r0 sys 0; 9f .data 9: sys write; 0:..; .. .text inc r5 bic $1,r5 mov (sp)+,r0 rts r5 7727;114303;110107;114145 / q0: 141100; 16201; 02154; 10216 q1: 41233;154404;136454; 22153 q2: 141016;111747; 07541; 52530 / / /p0 = -.24013 91795 59210 50986 8484 d2 /p1 = .30957 29282 15376.globl pow, _pow .globl log, exp _pow: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 movf 12.(r5),fr1 jsr pc,pow mov (sp)+,r5 rts pc pow: / 0^0~ is 0 tstf fr0 cfcc bne 1f tstf fr1 cfcc beq bad rts pc 1: / -^i is +^i fixed sign bpl 1f movf fr1,-(sp) modf $one,fr1 cfcc bne bad1 movf (sp)+,fr1 absf fr0 jsr pc,1f bes bad movf fr1,-(sp) modf $half,fr1 cfcc beq 2f negf fr0 2: movf (sp)+,fr1 rts pc 1: jsr pc,log bes 1f mulf fr1,fr0 jsr pc,exp 1: rts pc bad1: movf (sp)+,fr1 bad: sec rts pc one = 40200 half = 40000 mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 movf 12.(r5),fr1 jsr pc,pow mov (sp)+,r5 rts pc pow: / 0^0~ is 0 tstf fr0 cfcc bne 1f tstf fr1 cfcc beq bad rts pc 1: / -^i is +^i fixed sign bpl 1f movf fr1,-(sp) modf $one,fr1 cfcc bne bad1 movf (sp)+,fr1 absf fr0 jsr pc,1f bes bad movf fr1,-(sp) modf $half,fr1 cfcc beq 2f negf fr0 2: movf (sp)+,fr1 rts pc 1: jsr pc,log bes 1f mulf fr1,fr0 jsr pc,exp 1: rts pc bad1: movf (sp)+,fr1 bad:/ putw/putc -- write words/characters on output file / / fcreat -- create an output file for use by put(w|c) / / calling sequences -- / / mov $filename,r0 / jsr r5,fcreat; ioptr / / on return ioptr is set up for use by put or error / bit is set if file could not be created. / / mov(b) thing,r0 / jsr r5,put(w|c)1; ioptr / / the character or word is written out. / / jsr r5,flush; ioptr / / the buffer is fled. / .globl putc, putw, flush, fcreat fcreat: mov r1,-(sp) mov (r5)+,r1 mov r0,0f sys 0; 9f .data 9: sys creat; 0:..; 666 .text bes 1f mov r0,(r1)+ 2: clr (r1)+ clr (r1)+ mov (sp)+,r1 rts r5 1: mov $-1,(r1)+ mov (sp)+,r1 sec rts r5 .data putw: mov (r5),8f mov (r5)+,9f mov r0,-(sp) jsr r5,putc; 8:.. mov (sp)+,r0 swab r0 jsr r5,putc; 9:.. rts r5 .text putc: mov r1,-(sp) mov (r5)+,r1 1: dec 2(r1) bge 1f mov r0,-(sp) jsr pc,fl mov (sp)+,r0 br 1b 1: movb r0,*4(r1) inc 4(r1) mov (sp)+,r1 rts r5 flush: mov r0,-(sp) mov r1,-(sp) mov (r5)+,r1 jsr pc,fl mov (sp)+,r1 mov (sp)+,r0 rts r5 fl: mov r1,r0 add $6,r0 mov r0,-(sp) mov r0,0f mov 4(r1),0f+2 beq 1f sub (sp),0f+2 mov (r1),r0 sys 0; 9f .data 9: sys write; 0:..; .. .text 1: mov (sp)+,4(r1) mov $512.,2(r1) rts pc ; 8:.. mov (sp)+,r0 swab r0 jsr r5,putc; 9:.. rts r5 .text putc: mov r1,-(sp) mov (r5)+,r1 1: dec 2(r1) bge 1f mov r0,-(sp) jsr pc,fl mov (sp)+,r0 br 1b 1: movb r0,*4(r1) inc 4(r1) mov (sp)+,r1 rts r5 flush: mov r0,-(sp) mov r1,-(sp) mov (r5)+,r1 jsr pc,fl mov (sp)+,/ / copyright 1972 bell telephone laboratories inc. / / quicker sort / mov $base,r1 / mov $base+[n*width],r2 / mov $width,r3 / jsr pc,qsort / r0,r1,r2,r3,r4 are used .globl qsort .globl compare qsort: mov r5,-(sp) mov r4,-(sp) bit $1,r3 bne 1f bit $1,r1 bne 1f cmp r3,$2 bne 2f mov $exch1,exchange br 3f 2: mov r3,r5 clc ror r5 mov r5,width mov $exchw,exchange br 3f 1: mov $exchb,exchange 3: jsr pc,qs1 mov (sp)+,r4 mov (sp)+,r5 rts pc qs1: mov r1,r5 neg r5 add r2,r5 bgt 1f rts pc 1: clr r4 dvd r3,r4 asr r4 mpy r3,r4 mov r5,r4 add r1,r4 mov r1,-(sp) mov r2,-(sp) loop: cmp r1,r4 bhis loop1 mov r1,r0 jsr pc,compare bgt loop1 add r3,r1 br loop loop1: cmp r2,r4 blos 1f sub r3,r2 mov r2,r0 jsr pc,compare bge loop1 jsr pc,*exchange cmp r1,r4 bne loop mov r2,r4 br loop 1: cmp r1,r4 beq 1f jsr pc,*exchange mov r1,r4 br loop1 1: mov (sp)+,r2 mov r4,-(sp) mov r4,r1 add r3,r1 mov r2,r0 sub r1,r0 sub 2(sp),r4 cmp r0,r4 blo 1f mov (sp)+,r0 mov (sp)+,r4 mov r1,-(sp) mov r2,-(sp) mov r0,r2 mov r4,r1 1: jsr pc,qs1 mov (sp)+,r2 mov (sp)+,r1 br qs1 exchb: mov r1,-(sp) mov r2,-(sp) mov r3,r5 1: movb (r1),r0 movb (r2),(r1)+ movb r0,(r2)+ sob r5,1b mov (sp)+,r2 mov (sp)+,r1 rts pc exchw: mov r1,-(sp) mov r2,-(sp) mov width,r5 1: mov (r1),r0 mov (r2),(r1)+ mov r0,(r2)+ sob r5,1b mov (sp)+,r2 mov (sp)+,r1 rts pc exch1: mov (r1),r0 mov (r2),(r1) mov r0,(r2) rts pc .bss exchange: .=.+2 width: .=.+2 o 1f mov (sp)+,r0 mov (s/ random fixed point number generator .globl rand, srand .globl _rand, _srand _srand: mov 2(sp),ranx rts pc srand: mov r0,ranx rts pc _rand: rand: mov r1,-(sp) mov ranx,r1 mpy $13077.,r1 add $6925.,r1 mov r1,r0 mov r0,ranx bic $100000,r0 mov (sp)+,r1 rts pc .data ranx: 1 v width,r5 1: mov (r1),r0 mov (r2),(r1)+ mov r0,(r2)+ sob r5,1b mov (sp)+,r2 mov (sp)+,r1 rts pc exch1: mov (r1),r0 mov (r2),(r1) mov r0,(r2) rts pc .bss exchange: .=.+2 width: .=.+2 o 1f mov (sp)+,r0 mov (s/ savr5 - for as progs that call c-callable entries .globl savr5 .bss savr5: .=.+2 nd: mov 2(sp),ranx rts pc srand: mov r0,ranx rts pc _rand: rand: mov r1,-(sp) mov ranx,r1 mpy $13077.,r1 add $6925.,r1 mov r1,r0 mov r0,ranx bic $100000,r0 mov (sp)+,r1 rts pc .data ranx: 1 v width,r5 1: mov (r1),r0 mov (r2),(r1)+ mov r0,(r2)+ sob r5,1b mov (sp)+,r2 mov (sp)+,r1 rts pc exch1: mov (r1),r0 mov (r2),(r1) mov r0,(r2) rts pc .bss exchange: .=.+2 width: .=.+2 o 1f mov (sp)+,r0 mov (sldfps = 170100^tst stfps = 170200^tst / .globl sin, _sin .globl cos, _cos / / floating point sin/cos / replaces the value in fr0 by its sin/cos / there are no error exits / coefficients are #3370 from Hart & Cheney / _sin: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,sin br 1f _cos: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,cos 1: mov (sp)+,r5 rts pc cos: absf fr0 mov $1,-(sp) br 1f sin: clr -(sp) 1: stfps -(sp) ldfps $200 movf fr1,-(sp) movf fr2,-(sp) mov r0,-(sp) / / quadrant reduction - arg = (2/J)x / -1 < arg < 1 / movf fr0,-(sp) absf fr0 modf frpi2,fr0 modf $fourth,fr1 mulf $four,fr1 movfi fr1,r0 add 34(sp),r0 movf $one,fr1 inc r0 ror r0 bcs 1f subf $one,fr0 1: ror r0 bcc 1f negf fr0 1: tstf (sp)+ cfcc bpl 1f negf fr0 1: movf fr0,fr1 mulf fr0,fr1 /arg^2 / movf p4,fr2 mulf fr1,fr2 addf p3,fr2 mulf fr1,fr2 addf p2,fr2 mulf fr1,fr2 addf p1,fr2 mulf fr1,fr2 addf p0,fr2 mulf fr2,fr0 / zP(z^2) / movf fr1,fr2 addf q3,fr2 mulf fr1,fr2 addf q2,fr2 mulf fr1,fr2 addf q1,fr2 mulf fr1,fr2 addf q0,fr2 / Q(z^2) / divf fr2,fr0 / zP(z^2)/Q(z^2) / mov (sp)+,r0 movf (sp)+,fr2 movf (sp)+,fr1 ldfps (sp)+ tst (sp)+ / clc /tst clears carry rts pc / fourth = 37600 one = 40200 four = 40600 / .data frpi2: 40042;174603; 67116; 42025 / p0: 046117;031130;175220;165273 p1: 145626;154170;031651;104637 p2: 044726;162341;133224;052302 p3: 143530;056427;005061;125021 p4: 042021;174005;170441;175607 q0: 046003;163716;123445;167144 q1: 044707;047147;032436;120046 q2: 043423;156142;064161;007314 q3: 042004;123513;026637;160477 / /p0 = .13578 84097 87737 56690 92680 d8 /p1 = -.49429 08100 90284 41611 58627 d7 /p2 = .44010 30535 37526 65019 44918 d6 /p3 = -.13847 27249 98245 28730 54457 d5 /p4 = .14596 88406 66576 87222 26959 d3 /q0 = .86445 58652 92253 44299 15149 d7 /q1 = .40817 92252 34329 97493 95779 d6 /q2 = .94630 96101 53820 81805 71257 d4 /q3 = .13265 34908 78613 63589 11494 d3 /q4 = .1 d1 144 q1: 044707;047147;032436;120046 ldfps = 170100^tst stfps = 170200^tst / / sqrt replaces the f.p. number in fr0 by its / square root. newton's method / .globl sqrt, _sqrt / / _sqrt: mov r5,-(sp) mov sp,r5 movf 4(r5),fr0 jsr pc,sqrt mov (sp)+,r5 rts pc sqrt: tstf fr0 cfcc bne 1f clc rts pc /sqrt(0) 1: bgt 1f clrf fr0 sec rts pc / sqrt(-a) 1: mov r0,-(sp) stfps -(sp) mov (sp),r0 bic $!200,r0 / retain mode ldfps r0 movf fr1,-(sp) movf fr2,-(sp) / movf fr0,fr1 movf fr0,-(sp) asr (sp) add $20100,(sp) movf (sp)+,fr0 /initial guess mov $4,r0 1: movf fr1,fr2 divf fr0,fr2 addf fr2,fr0 mulf $half,fr0 / x = (x+a/x)/2 sob r0,1b 2: movf (sp)+,fr2 movf (sp)+,fr1 ldfps (sp)+ mov (sp)+,r0 clc rts pc / half = 40000 v (sp)+,r5 rts pc sqrt: tstf fr0 cfcc bne 1f clc rts pc /sqrt(0) 1: bgt 1f clrf fr0 sec rts pc / sqrt(-a) 1: mov r0,-(sp) stfps -(sp) mov (sp),r0 bic $!200,r0 / retain mode ldfps r0 movf fr1,-(sp) movf fr2,-(sp) / movf fr0,fr1 movf fr0,-(sp) asr (sp) add $20100,(sp) movf (sp)+,f/ switch -- switch on contents of r0 / / / calling sequence -- / / jsr r5,switch; swtab / / r0 is looked up in swtab and if found / control is returned to the corresponding place / if r0 is not found, the next inline instruction is / executed / / swtab format -- / / swtab: / val1; ret1 / val2; ret2 / ... / valn; retn / ..; 0 / .globl switch switch: mov r1,-(sp) mov (r5)+,r1 1: cmp r0,(r1)+ beq 1f tst (r1)+ bne 1b 2: mov (sp)+,r1 rts r5 1: mov (r1)+,r1 beq 2b mov r1,r5 br 2b )+,f/ return name of current tty .globl lnxx, _lnxx, lnff _lnxx: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 jsr pc,lnff mov (sp)+,r5 rts pc lnxx: clr r0 lnff: mov $"xx,name tst -(sp) sys fstat; buf bes er2 mov buf+2,(sp) sys stat; dev; buf+2 cmp buf,buf+2 bne er2 sys open; dev; 0 bes er2 mov r0,r1 1: mov r1,r0 sys read; buf; 16. bes er1 cmp r0,$16. bne er1 mov $buf,r0 cmp (r0)+,(sp) bne 1b cmp (r0)+,$"ln bne 1b tstb (r0) beq 1b movb (r0)+,name cmpb (r0),$0 beq er movb (r0)+,name+1  cmpb (r0),$0 beq er1 br 1b er: movb $0,name+1 er1: mov r1,r0 sys close er2: tst (sp)+ mov name,r0 rts pc .data dev: .even .bss buf: .=.+42. name: .=.+2 tst -(sp) sys fstat; buf bes er2 mov buf+2,(sp) sys stat; dev; buf+2 cmp buf,buf+2 bne er2 sys open; dev; 0 bes er2 mov r0,r1 1: mov r1,r0 sys read; buf; 16. bes er1 cmp r0,$16. bne er1 mov $buf,r0 cmp (r0)+,(sp) bne 1b cmp (r0)+,$"ln bne 1b tstb (r0) beq 1b movb (r0)+,name cmpb (r0),$0 beq er movb (r0)+,name+1 / MOD2.15 - UNIX SUPPORT GROUP / / copyright 1972 bell telephone laboratories inc. / / bas0 -- basic .globl main .globl sin, cos, log, exp, atan, pow .globl rand, srand .globl fptrap one = 40200 main: sys signal; 4; fptrap setd sys time mov r1,r0 mov r0,randx jsr pc,srand sys signal; 2; 1 ror r0 bes 1f sys signal; 2; intrup 1: mov sp,gsp clr seeka mov $'a,r1 1: movb r1,tmpf+8 sys stat; tmpf; line bes 1f inc r1 cmp r1,$'z blos 1b br 2f 1: sys creat; tmpf; 600 bes 2f mov r0,tfo sys open; tmpf; 0 bec 1f 2: mov $3f,r0 jsr pc,print sys exit 3: ; .even 1: mov r0,tfi jsr pc,isymtab cmp (sp),$2 blt loop mov 4(sp),argname sys 0; 9f .data 9: sys open; argname: b.out; 0 .text bes 1f mov r0,fi br loop 1: mov $1f,r0 jsr pc,print br loop 1: ; .even intrup: sys signal; 2; intrup mov $'\n,r0 jsr r5,putc jsr r5,error ; .even loop: mov gsp,sp clr lineno jsr pc,rdline mov $line,r3 1: movb (r3),r0 jsr pc,digit br 1f jsr r5,atoi; nextc cmp r0,$' / bne 1f mov $lintab,r3 mov r1,r0 bgt 2f jsr pc,serror 2: cmp r0,(r3) beq 2f tst (r3) beq 2f add $6,r3 br 2b 2: cmp r3,$elintab-12. blo 2f jsr r5,error ; .even 2: mov r0,(r3)+ mov seeka,(r3)+ mov tfo,r0 sys 0; 9f .data 9: sys seek; seeka:..; 0 .text mov $line,r0 jsr pc,size inc r0 add r0,seeka mov r0,0f mov tfo,r0 sys 0; 9f .data 9: sys write; line; 0:.. .text br loop 1: mov $line,r3 jsr pc,singstat br loop nextc: movb (r3)+,r0 rts r5 size: clr -(sp) 1: tstb (r0) beq 1f inc (sp) cmpb (r0)+,$'\n bne 1b 1: mov (sp)+,r0 rts pc rdline: mov $line,0f 1: mov fi,r0 sys 0; 9f .data 9: sys read; 0:..; 1 .text bes 2f tst r0 beq 2f cmp 0b,$line+99. bhis 2f / bad check, but a check movb *0b,r0 inc 0b cmp r0,$'\n bne 1b clrb *0b rts pc 2: mov fi,r0 beq 1f sys close clr fi br 1b 1: jmp _done error: mov fi,r0 beq 1f sys close clr fi 1: mov fo,r0 cmp r0,$1 beq 1f sys close mov $1,fo 1: tst lineno beq 1f jsr pc,nextlin br 1f mov $line,r0 jsr pc,print 1: mov r5,r0 jsr pc,print jmp loop serror: dec r3 tst fi beq 1f sys close clr fi 1: mov $line,r1 1: cmp r1,r3 bne 2f mov $'_,r0 jsr r5,putc mov $10,r0 jsr r5,putc 2: movb (r1),r0 jsr r5,putc cmpb (r1)+,$'\n bne 1b jmp loop print: mov r0,0f jsr pc,size mov r0,0f+2 mov fo,r0 sys 0; 9f .data 9: sys write; 0:..; .. .text rts pc digit: cmp r0,$'0 blo 1f cmp r0,$'9 bhi 1f add $2,(sp) 1: rts pc alpha: cmp r0,$'a blo 1f  cmp r0,$'z bhi 1f add $2,(sp) 1: rts pc name: mov $nameb,r1 clr (r1) clr 2(r1) 1: cmp r1,$nameb+4 bhis 2f movb r0,(r1)+ 2: movb (r3)+,r0 jsr pc,alpha br 2f br 1b 2: jsr pc,digit br 2f br 1b 2: mov $resnam,r1 1: cmp nameb,(r1) bne 2f cmp nameb+2,2(r1) bne 2f sub $resnam,r1 asr r1 add $2,(sp) rts pc 2: add $4,r1 cmp r1,$eresnam blo 1b mov $symtab,r1 1: tst (r1) beq 1f cmp nameb,(r1) bne 2f cmp nameb+2,2(r1) bne 2f rts pc 2: add $14.,r1 br 1b 1: cmp r1,$esymtab-28. blo 1f jsr r5,error ; .even 1: mov nameb,(r1) mov nameb+2,2(r1) clr 4(r1) clr 14.(r1) rts pc skip: cmp r0,$' / bne 1f movb (r3)+,r0 br skip 1: rts pc putc: tstb drflg beq 1f jsr pc,drput rts r5 1: mov r0,ch mov $1,r0 sys write; ch; 1 rts r5 nextlin: clr -(sp) mov $lintab,r1 1: tst (r1) beq 1f cmp lineno,(r1) bhi 2f mov (sp),r0 beq 3f cmp (r0),(r1) blos 2f 3: mov r1,(sp) 2: add $6,r1 br 1b 1: mov (sp)+,r1 beq 1f mov (r1)+,lineno mov (r1)+,0f mov tfi,r0 sys 0; 9f .data 9: sys seek; 0:..; 0 .text mov tfi,r0 sys read; line; 100. add $2,(sp) 1: rts pc getloc: mov $lintab,r1 1: tst (r1) beq 1f cmp r0,(r1) beq 2f add $6,r1 br 1b 1: jsr r5,error vt: .even resnam: eresnam: symtnam: esymtnam: .data fo: 1 .bss drx: .=.+8 dry: .=.+8 drfo: .=.+2 ch: .=.+1 drflg: .=.+1 randx: .=.+2 fsgn: .=.+2 gsp: .=.+2 forp: .=.+2 exprloc:.=.+2 sstack: .=.+2 sublev: .=.+2 val: .=.+2 line: .=.+100. tfi: .=.+2 fi: .=.+2 lineno: .=.+2 nameb: .=.+6 tfo: .=.+2 symtab: .=.+1000.; esymtab: space: .=.+5000.; espace: exline: .=.+1000.; eexline: lintab: .=.+1000.; elintab: stack: .=.+1000.; estack: eresnam: symtnam: esymtnam: .data fo: 1 .bss drx: .=.+8 dry: .=.+8 drfo: .=.+2 ch: .=.+1 drflg: .=.+1 randx: .=.# /* * C compiler-- first pass header */ /* * parameters */ #define LTYPE long /* change to int if no long consts */ #define MAXINT 077777 /* Largest positive short integer */ #define NCPS 8 /* # chars per symbol */ #define HSHSIZ 300 /* # entries in hash table for names */ #define CMSIZ 40 /* size of expression stack */ #define SSIZE 20 /* size of other expression stack */ #define SWSIZ 200 /* size of switch table */ #define NMEMS 128 /* Number of members in a structure */ #define NBPW 16 /* bits per word, object machine */ #define NBPC 8 /* bits per character, object machine */ #define NCPW 2 /* chars per word, object machine */ #define LNCPW 2 /* chars per word, compiler's machine */ #define STAUTO (-6) /* offset of first auto variable */ #define STARG 4 /* offset of first argument */ #define NULL 0 /* null ptr */ /* * # bytes in primitive types */ #define SZCHAR 1 #define SZINT 2 #define SZPTR 2 #define SZFLOAT 4 #define SZLONG 4 #define SZDOUB 8 /* * format of a structure description */ struct str { int ssize; /* structure size */ struct hshtab **memlist; /* member list */ }; /* * For fields, strp points here instead. */ struct field { int flen; /* field width in bits */ int bitoffs; /* shift count */ }; /* * Structure of tree nodes for operators */ struct tnode { int op; /* operator */ int type; /* data type */ int *subsp; /* subscript list (for arrays) */ struct str *strp; /* structure description for structs */ struct tnode *tr1; /* left operand */ struct tnode *tr2; /* right operand */ }; /* * Tree node for constants */ struct cnode { int op; int type; int *subsp; struct str *strp; int value; }; /* * Tree node for long constants */ struct lnode { int op; int type; int *subsp; struct str *strp; LTYPE lvalue; }; /* * tree node for floating * constants */ struct fnode { int op; int type; int *subsp; struct str *strp; char *cstr; }; /* * Structure of namelist */ struct hshtab { char hclass; /* storage class */ char hflag; /* various flags */  int htype; /* type */ int *hsubsp; /* subscript list */ struct str *hstrp; /* structure description */ int hoffset; /* post-allocation location */ char name[NCPS]; /* ASCII name */ }; /* * Place used to keep dimensions * during declarations */ struct tdim { int rank; int dimens[5]; }; /* * Table for recording switches. */ struct swtab { int swlab; int swval; }; char cvtab[4][4]; char filename[64]; int opdope[]; char ctab[]; char symbuf[NCPS+2]; int hshused; struct hshtab hshtab[HSHSIZ]; struct tnode **cp; struct tnode *cmst[CMSIZ]; int isn; struct swtab swtab[SWSIZ]; struct swtab *swp; int contlab; int brklab; int retlab; int deflab; int autolen; int peeksym; int peekc; int eof; int line; char *funcbase; char *curbase; char *coremax; struct hshtab *defsym; struct hshtab *funcsym; int xdflg; int proflg; int stflg; struct hshtab *csym; int cval; LTYPE lcval; int nchstr; int nerror; struct hshtab **paraml; struct hshtab **parame; int strflg; int mosflg; int initflg; int inhdr; char obuf[518]; char sbuf[518]; int regvar; int bitoffs; struct tnode funcblk; char cvntab[]; char numbuf[64]; struct hshtab **memlist; int nmems; struct hshtab structhole; /* operators */ #define NULLOP 218 #define EOF 0 #define SEMI 1 #define LBRACE 2 #define RBRACE 3 #define LBRACK 4 #define RBRACK 5 #define LPARN 6 #define RPARN 7 #define COLON 8 #define COMMA 9 #define FSEL 10 #define KEYW 19 #define NAME 20 #define CON 21 #define STRING 22 #define FCON 23 #define SFCON 24 #define LCON 25 #define SLCON 26 #define SIZEOF 91 #define INCBEF 30 #define DECBEF 31 #define INCAFT 32 #define DECAFT 33 #define EXCLA 34 #define AMPER 35 #define STAR 36 #define NEG 37 #define COMPL 38 #define DOT 39 #define PLUS 40 #define MINUS 41 #define TIMES 42 #define DIVIDE 43 #define MOD 44 #define RSHIFT 45 #define LSHIFT 46 #define AND 47 #define OR 48 #define EXOR 49 #define ARROW 50 #define ITOF 51 #define FTOI 52 #define LOGAND 53 #define LOGOR 54 #define FTOL 56 #define LTOF 57 #define ITOL 58 #define LTOI 59 #define ITOP 13 #define PTOI 14 #define LTOP 15 #define EQUAL 60 #define NEQUAL 61 #define LESSEQ 62 #define LESS 63 #define GREATEQ 64 #define GREAT 65 #define LESSEQP 66 #define LESSP 67 #define GREATQP 68 #define GREATP 69 #define ASPLUS 70 #define ASMINUS 71 #define ASTIMES 72 #define ASDIV 73 #define ASMOD 74 #define ASRSH 75 #define ASLSH 76 #define ASSAND 77 #define ASOR 78 #define ASXOR 79 #define ASSIGN 80 #define QUEST 90 #define MAX 93 #define MAXP 94 #define MIN 95 #define MINP 96 #define SEQNC 97 #define CALL 100 #define MCALL 101 #define JUMP 102 #define CBRANCH 103 #define INIT 104 #define SETREG 105 #define RFORCE 110 #define BRANCH 111 #define LABEL 112 #define NLABEL 113 #define RLABEL 114 #define SEOF 200 /* stack EOF marker in expr compilation */ /* types */ #define INT 0 #define CHAR 1 #define FLOAT 2 #define DOUBLE 3 #define STRUCT 4 #define LONG 6 #define ALIGN 01 #define TYPE 07 #define TYLEN 2 #define XTYPE (03<<3) #define PTR 010 #define FUNC 020 #define ARRAY 030 /* storage classes */ #define KEYWC 1 #define MOS 10 #define AUTO 11 #define EXTERN 12 #define STATIC 13 #define REG 14 #define STRTAG 15 #define ARG 16 #define ARG1 17 /* keywords */ #define GOTO 20 #define RETURN 21 #define IF 22 #define WHILE 23 #define ELSE 24 #define SWITCH 25 #define CASE 26 #define BREAK 27 #define CONTIN 28 #define DO 29 #define DEFAULT 30 #define FOR 31 /* characters */ #define BSLASH 117 #define SHARP 118 #define INSERT 119 #define PERIOD 120 #define SQUOTE 121 #define DQUOTE 122 #define LETTER 123 #define DIGIT 124 #define NEWLN 125 #define SPACE 126 #define UNKN 127 /* * Special operators in intermediate code */ #define BDATA 200 #define WDATA 201 #define PROG 202 #define DATA 203 #define BSS 204 #define CSPACE 205 #define SSPACE 206 #define SYMDEF 207 #define SAVE 208 #define RETRN 209 #define EVEN 210 #define PROFIL 212 #define SWIT 213 #define EXPR 214 #define SNAME 215 #define RNAME 216 #define ANAME 217 #define SETSTK 219 #define SINIT 220 /* Flag bits */ #define BINARY 01 #define LVALUE 02 #define RELAT 04 #define ASSGOP 010 #define LWORD 020 #define RWORD 040 #define COMMUTE 0100 #define RASSOC 0200 #define LEAF 0400 /* * Conversion codes */ #define ITF 1 #define ITL 2 #define LTF 3 #define ITP 4 #define PTI 5 #define FTI 6 #define LTI 7 #define FTL 8 #define LTP 9 #define XX 15 /* * symbol table flags */ #define FNDEL 01 #define FNUND 02 #define FKEYW 04 #define FFIELD 020 #define FINIT 040 /* * functions */ char *sbrk(); struct tnode *tree(); char *copnum(); struct tnode *convert(); struct tnode *chkfun(); struct tnode *disarray(); struct tnode *block(); struct cnode *cblock(); struct fnode *fblock(); char *gblock(); struct tnode *pexpr(); struct str *strdec(); #define LTF 3 #define ITP 4 #define PTI 5 #define FTI 6 #define LTI 7 #define FTL 8 #define LTP 9 #define XX 15 /* * symbol table flags */ #define FNDEL 01 #define FNUND 02 #define FKEYW 04 #define FFIELD 020 #define FINIT 040 /* * functions */ char *sbrk(); struct tnode *tree(); char *copnum(); struct tnode *convert# /* C compiler * * * * Called from cc: * c0 source temp1 temp2 [ profileflag ] * temp1 gets most of the intermediate code; * strings are put on temp2, which c1 reads after temp1. */ #include "c0.h" int isn 1; int stflg 1; int peeksym -1; int line 1; struct tnode funcblk { NAME, 0, NULL, NULL, NULL, NULL }; struct kwtab { char *kwname; int kwval; } kwtab[] { "int", INT, "char", CHAR, "float", FLOAT, "double", DOUBLE, "struct", STRUCT, "long", LONG, "auto", AUTO, "extern", EXTERN,  "static", STATIC, "register", REG, "goto", GOTO, "return", RETURN, "if", IF, "while", WHILE, "else", ELSE, "switch", SWITCH, "case", CASE, "break", BREAK, "continue", CONTIN, "do", DO, "default", DEFAULT, "for", FOR, "sizeof", SIZEOF, 0, 0, }; main(argc, argv) char *argv[]; { extern fin; register char *sp; register i; register struct kwtab *ip; if(argc<3) { error("Arg count"); exit(1); } if((fin=open(argv[1],0))<0) { error("Can't find %s", argv[1]); exit(1); } if (fcreat(argv[2], obuf)<0 || fcreat(argv[3], sbuf)<0) { error("Can't create temp"); exit(1); } if (argc>4) proflg++; /* * The hash table locations of the keywords * are marked; if an identifier hashes to one of * these locations, it is looked up in in the keyword * table first. */ for (ip=kwtab; (sp = ip->kwname); ip++) { i = 0; while (*sp) i =+ *sp++; hshtab[i%HSHSIZ].hflag = FKEYW; } coremax = funcbase = curbase = sbrk(0); while(!eof) extdef(); outcode("B", EOF); strflg++; outcode("B", EOF); fflush(obuf); fflush(sbuf); exit(nerror!=0); } /* * Look up the identifier in symbuf in the symbol table. * If it hashes to the same spot as a keyword, try the keyword table * first. An initial "." is ignored in the hash. * Return is a ptr to the symbol table entry. */ lookup() { int ihash; register struct hshtab *rp; register char *sp, *np; ihash = 0; sp = symbuf; if (*sp=='.') sp++; while (sphflag&FKEYW) if (findkw()) return(KEYW); while (*(np = rp->name)) { for (sp=symbuf; sp= &hshtab[HSHSIZ]) rp = hshtab; } if(++hshused >= HSHSIZ) { error("Symbol table overflow"); exit(1); } rp->hclass = 0; rp->htype = 0; rp->hoffset = 0; rp->subsp = NULL; rp->strp = NULL; rp->hflag =| xdflg; sp = symbuf; for (np=rp->name; spkwname); kp++) { p1 = wp; while (*p1 == *p2++) if (*p1++ == '\0') { cval = kp->kwval; return(1); } } return(0); } /* * Return the next symbol from the input. * peeksym is a pushed-back symbol, peekc is a pushed-back * character (after peeksym). * mosflg means that the next symbol, if an identifier, * is a member of structure or a structure tag, and it * gets a "." prepended to it to distinguish * it from other identifiers. */ symbol() { register c; register char *sp; register tline; if (peeksym>=0) { c = peeksym; peeksym = -1; if (c==NAME) mosflg = 0; return(c); } if (peekc) { c = peekc; peekc = 0; } else if (eof) return(EOF); else c = getchar(); loop: switch(ctab[c]) { case SHARP: if ((c=symbol())!=CON) { error("Illegal #"); return(c); } tline = cval; while (ctab[peekc]==SPACE) peekc = getchar(); if (peekc=='"') { sp = filename; while ((c = mapch('"')) >= 0) *sp++ = c; *sp++ = 0; } else if (peekc !='\n') error("Illegal #"); peekc = 0; while (getchar()!='\n' && eof==0); line = tline; return(symbol()); case INSERT: /* ignore newlines */ inhdr = 1; c = getchar(); goto loop; case NEWLN: if (!inhdr) line++; inhdr = 0; case SPACE: c = getchar(); goto loop; case EOF: eof++; return(0); case PLUS: return(subseq(c,PLUS,INCBEF)); case MINUS: return(subseq(c,subseq('>',MINUS,ARROW),DECBEF)); case ASSIGN: if (subseq(' ',0,1)) return(ASSIGN); if (subseq('=',0,1)) return(EQUAL); c = symbol(); if (c>=PLUS && c<=EXOR) { if (spnextchar() != ' ' && (c==MINUS || c==AND || c==TIMES)) { error("Warning: assignment operator assumed"); nerror--; } return(c+ASPLUS-PLUS); } if (c==ASSIGN) return(EQUAL); peeksym = c; return(ASSIGN); case LESS: if (subseq(c,0,1)) return(LSHIFT); return(subseq('=',LESS,LESSEQ)); case GREAT: if (subseq(c,0,1)) return(RSHIFT); return(subseq('=',GREAT,GREATEQ)); case EXCLA: return(subseq('=',EXCLA,NEQUAL)); case BSLASH: if (subseq('/', 0, 1)) return(MAX); goto unkn; case DIVIDE: if (subseq('\\', 0, 1)) return(MIN); if (subseq('*',1,0)) return(DIVIDE); while ((c = spnextchar()) != EOF) { peekc = 0; if (c=='*') { if (spnextchar() == '/') { peekc = 0; c = getchar(); goto loop; } } } eof++; error("Nonterminated comment"); return(0); case PERIOD: case DIGIT: peekc = c; return(getnum()); case DQUOTE: cval = isn++; return(STRING); case SQUOTE: return(getcc()); case LETTER: sp = symbuf; if (mosflg) { *sp++ = '.'; mosflg = 0; } while(ctab[c]==LETTER || ctab[c]==DIGIT) { if (spc||c>'9')) break; } else if (c=='x' || c=='X') { if (base!=8 || lcval!=0 || sym!=CON) error(nsyn); base = 16; } else if ((c=='l' || c=='L') && sym==CON) { c = getchar(); sym = LCON; break; } else break; } peekc = c; if (sym==FCON) { np[-1] = 0; cval = np-numbuf; return(FCON); }  if (sym==CON && (lcval<0 || lcval>MAXINT&&base==10 || (lcval>>1)>MAXINT)) { error("Note: constant is long"); nerror--; sym = LCON; } cval = lcval; return(sym); } /* * If the next input character is c, return b and advance. * Otherwise push back the character and return a. */ subseq(c,a,b) { if (spnextchar() != c) return(a); peekc = 0; return(b); } /* * Write out a string, either in-line * or in the string temp file labelled by * lab. */ putstr(lab, amax) { register int c, max; nchstr = 0; max = amax; if (lab) { strflg++; outcode("BNB", LABEL, lab, BDATA); max = 10000; } else outcode("B", BDATA); while ((c = mapch('"')) >= 0) { if (nchstr < max) { nchstr++; outcode("1N", c & 0377); } } if (nchstr < max) { nchstr++; outcode("10"); } outcode("0"); strflg = 0; } /* * read a single-quoted character constant. * The routine is sensitive to the layout of * characters in a word. */ getcc() { register int c, cc; register char *ccp; cval = 0; ccp = &cval; cc = 0; while((c=mapch('\'')) >= 0) if(cc++ < LNCPW) *ccp++ = c; if (cc>LNCPW) error("Long character constant"); return(CON); } /* * Read a character in a string or character constant, * detecting the end of the string. * It implements the escape sequences. */ mapch(ac) { register int a, c, n; static mpeek; c = ac; if (a = mpeek) mpeek = 0; else a = getchar(); loop: if (a==c) return(-1); switch(a) { case '\n': case '\0': error("Nonterminated string"); peekc = a; return(-1); case '\\': switch (a=getchar()) { case 't': return('\t'); case 'n': return('\n'); case 'b': return('\b'); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': n = 0; c = 0; while (++c<=3 && '0'<=a && a<='7') { n =<< 3; n =+ a-'0'; a = getchar(); } mpeek = a; return(n); case 'r': return('\r'); case '\n': if (!inhdr) line++; inhdr = 0; a = getchar(); goto loop; } } return(a); } /* * Read an expression and return a pointer to its tree. * It's the classical bottom-up, priority-driven scheme. * The initflg prevents the parse from going past * "," or ":" because those delimiters are special * in initializer (and some other) expressions. */ struct tnode * tree() { int *op, opst[SSIZE], *pp, prst[SSIZE]; register int andflg, o; register struct hshtab *cs; int p, ps, os; struct lnode *lcp; curbase = funcbase; op = opst; pp = prst; cp = cmst; *op = SEOF; *pp = 06; andflg = 0; advanc: switch (o=symbol()) { case NAME: cs = csym; if (cs->hclass==0 && cs->htype==0) if(nextchar()=='(') { /* set function */ cs->hclass = EXTERN; cs->htype = FUNC; } else if (initflg) cs->hclass = EXTERN; else { cs->hclass = STATIC; error("%.8s undefined; func. %.8s", cs->name, funcsym->name); } *cp++ = nblock(cs); goto tand; case FCON: *cp++ = fblock(DOUBLE, copnum(cval)); goto tand; case LCON: cs = gblock(sizeof(*lcp)); cs->op = LCON; cs->type = LONG; cs->lvalue = lcval; *cp++ = cs; goto tand; case CON: *cp++ = cblock(cval); goto tand; /* fake a static char array */ case STRING: putstr(cval); cs = gblock(sizeof(*cs)); cs->hclass = STATIC; cs->hoffset = cval; *cp++ = block(NAME, ARRAY+CHAR, &nchstr, NULL, cs); tand: if(cp>=cmst+CMSIZ) { error("Expression overflow"); exit(1); } if (andflg) goto syntax; andflg = 1; goto advanc; case INCBEF: case DECBEF: if (andflg) o =+ 2; goto oponst; case COMPL: case EXCLA: case SIZEOF: if (andflg) goto syntax; goto oponst; case MINUS: if (!andflg) o = NEG; andflg = 0; goto oponst; case AND: case TIMES: if (andflg) andflg = 0; else if(o==AND) o = AMPER; else o = STAR; goto oponst; case LPARN: if (andflg) { o = symbol(); if (o==RPARN) o = MCALL; else { peeksym = o; o = CALL; andflg = 0; } } goto oponst; case RBRACK: case RPARN: if (!andflg) goto syntax; goto oponst; case DOT: case ARROW: mosflg++; break; } /* binaries */ if (!andflg) goto syntax; andflg = 0; oponst: p = (opdope[o]>>9) & 077; if ((o==COMMA || o==COLON) && initflg) p = 05; opon1: ps = *pp; if (p>ps || p==ps && (opdope[o]&RASSOC)!=0) { switch (o) { case INCAFT: case DECAFT: p = 37; break; case LPARN: case LBRACK: case CALL: p = 04; } if (op >= &opst[SSIZE-1]) { error("expression overflow"); exit(1); } *++op = o; *++pp = p; goto advanc; } --pp; switch (os = *op--) { case SEOF: peeksym = o; build(0); /* flush conversions */ return(*--cp); case COMMA: if (*op != CALL) os = SEQNC; break; case CALL: if (o!=RPARN) goto syntax; build(os); goto advanc; case MCALL: *cp++ = NULL; /* empty arglist */ os = CALL; break; case INCBEF: case INCAFT: case DECBEF: case DECAFT: *cp++ = cblock(1); break; case LPARN: if (o!=RPARN) goto syntax; goto advanc; case LBRACK: if (o!=RBRACK) goto syntax; build(LBRACK); goto advanc; } build(os); goto opon1; syntax: error("Expression syntax"); errflush(o); return(0); } char * copnum(len) { register char *s1, *s2, *s3; s1 = s2 = gblock((len+LNCPW-1) & ~(LNCPW-1)); s3 = numbuf; while (*s2++ = *s3++); return(s1); } pty arglist */ os = CALL; break; case INCBEF: case INCAFT: case DECBEF: case DECAFT: *cp++ = cblock(1); break; case LPARN: if (o!=RPARN) goto syntax; goto advanc; case LBRACK: if (o!=RBRACK) goto syntax; build(LBRAC w %5   @& 7 @?  @& @& M  # n  `̋ r,Wpe 787470 * & _  a     ww 5 ˥. 5`%A r,WpDe Ҥe%e ʋ %7jwb ^%,Xc  4 4 4 4 0e Ҕ%w  .  CҢ Ӌ7we w | v %7 j 7  ^  r e$ A! y4 %y ` Z7VR~%" " % & 7  %   *  7  w(& %2)> pe&&  % P& = % < %(%1 d% %)%/%* @e%P7& & % .>?=& & % -@A="& / % _\]_ & \ % __  * % +_  ~7 v%* l%/7 b_b Z _7J _ < _  _  ӕ.7 % {|%7 %_H%[_H[_H5/&_.60|_. _b_ w 7 ~7 | 5 5 `%0_ta%a%f%Ab%F_%.(v% vm m @ vv7w%0%90 %a%fW7 7`w`w %%N  Ԑ%0%9%%. '[47VwN%e%E   %N Ԑ%+%-%0.%9+%x%X%   %N %l%L % %%#  -% |vv W   ZRN@_w B >@-@w07 ,@w "7 C " fp e'     7 w "   Ew 7   %' %  wbw ^C_T 7 _Z  7$ y% 7*C $ r e A! y  1 .+  %0%7 te`  %7T   f7  ww \@e5@e5n  r e A! y0:ʋ"  ,%(ʕ  ʕ ʕ e e : % =  2  !   ʕ &  e?lef%P`U  _ 7e4 2}  _ %%" %/#$  "%e d    tE5% % uu- u-1 5+^7 y %@e@-i  ee}_ @5 r evA! y w%daN %_ N _ ? ed ?e%_ _ %_ w pN E wP    "*.[0 > F P \ d    h$R h6bh<&\hFLh & $&f @ f F f   \f  $.* * , * & * R & * \ *   !d |2d2( | n Z Z 2  (  Z Z H intcharfloatdoublestructlongautoexternstaticregistergotoreturnifwhileelseswitchcasebreakcontinuedodefaultforsizeofArg countCan't find %sCan't create tempBBSymbol table overflowIllegal #Illegal #Warning: assignment operator assumedNonterminated commentUnknown characterNumber syntaxNote: constant is longBNBB1N100Long character constantNonterminated string%.8s undefined; func. %.8sExpression overflowexpression overflowExpression syntaxHXhyHXHXh8iYyi9IXHHhhhHHYYHXHHHY)))9) 8H) ))8)H)) 9yyy9 H ) )9H)HYYH) 88H)H8 H) H) H) )H ) I  I  HH)) ) yy) YiyiHHXyxXyyyHXHY(i(HXyyyyxyyX_cvtab _filenam @_opdope _ctab _symbuf _hshused _hshtab _cp _cmst P_isn# _swtab _swp _contlab _brklab _retlab _deflab _autolen _peeksym# _peekc _eof _line# _funcbas _curbase _coremax _defsym _funcsym _xdflg _proflg _stflg# _csym _cval _lcval _nchstr _nerror _paraml _parame _strflg _mosflg _initflg _inhdr _obuf _sbuf _regvar _bitoffs _funcblk# _cvntab _numbuf @_memlist _nmems _structh _kwtab# L1L2L3L4L5L6L7L8L9L10L11L12L13L14L15L16L17 L18L19L20L21"L22*L23._main"~maincsv iargcargvipspL25L265_error _exit _open _fin L27LL28?_fcreat L10000xL29L30ML31L32L20003L35L20001_sbrk L37L20005_extdef L39__outcode L40a_fflush L10001L10002cret _lookup"~lookupnpihashrpspL43<L200076L47~_findkw"L41L20009lL49L48L20014L53L54cL20012~findkwp1p2kpwpL58L59"L20016L62L61L57_symbol"*L10007$ L100080 L10009> L10010F L10011P L10012\ L10013d L72hL91L92$L103L94RL118L88 L936L120L20024bL129<L106&L119L108\L109FL130LL101L74L121L105L87~symbol*csptlineL66LL67HL65 L68\L71hL20018_getchar L10006~L75L76yL77L20020L79L80L20022_mapch"L82L84L85L86L89L20030,L20032._subseq"L95lL20037fL96L20038L97_spnextc L98L10003L99L102L20039L104L110bL112~L113L116_getnum"p_getcc"`L123L10004L125L126L20027 L132~getnumpsymndigitcbasensynexpseennpL134L136tL20043L10017L10014L139L140L20041 L142L144&L145<L1468L138nL20045RL10018`L149hL10015L150L137RL20047L133L10019L151L152L10021 L1542L10022$L155,L10023>L160L10024L10025L10026|L161~subseqabcL163L162_putstr"~putstrlabmaxcamaxL1650L166L169>L20053L173 L174L175 L168L200498L172~getcc`ccpcccL177|L20055pL180L181 L10030 L10031 L10032 L10033 L10034 L188f L206 L209@ L210F L198 L197 L196L10036 L10037 L191L193~mapchL183acnacmpeekL184T L186Z L187L10038L192%L20056^ L10029L182b L2070 L20058 L2088 L211P _tree"j L10041 L10042 L10043L10044L10045L10046L10047$L10048.L214* L246 L232 L241 L251 L225, L237 L216 L253& L226R L227\ L224 L238 L10052^L10053hL263 L260 L257 L10057vL10058|L10059L10060L266( L278| L277n L276Z L2712 L268 L269 L272H ~treej lcpandflgopopstprstcsoppppsosL213 L10040 L217 _nextcha L218 L220 L222:_nblock L20061 _copnum" _fblock _gblock L20060 _cblock _block L228 L229UL230 L2340 L279}_errflus L212 L20062. L244 L248 L10049P L255\ L10050~ L256 L10054 L264 L265iL10056 _build L20063@ ~copnum lens1s2s3L281 osL213 L10040 L217 _nextcha L218 L220 L222:_nblock L20061 _copnum" _fblock _gblock L20060 _cblock _block L228 L229UL230 L2340 L279}_errflus L212 L20062. L244# /* * C compiler * * */ #include "c0.h" /* * Called from tree, this routine takes the top 1, 2, or 3 * operands on the expression stack, makes a new node with * the operator op, and puts it on the stack. * Essentially all the work is in inserting * appropriate conversions. */ build(op) { register int t1; int t2, t; register struct tnode *p1, *p2; struct tnode *p3; int dope, leftc, cvn, pcvn; /* * a[i] => *(a+i) */ if (op==LBRACK) { build(PLUS); op = STAR; } dope = opdope[op];  if ((dope&BINARY)!=0) { p2 = chkfun(disarray(*--cp)); t2 = p2->type; } p1 = *--cp; /* * sizeof gets turned into a number here. */ if (op==SIZEOF) { *cp++ = cblock(length(p1)); return; } if (op!=AMPER) { p1 = disarray(p1); if (op!=CALL) p1 = chkfun(p1); } t1 = p1->type; pcvn = 0; t = INT; switch (op) { /* end of expression */ case 0: *cp++ = p1; return; /* no-conversion operators */ case QUEST: if (p2->op!=COLON) error("Illegal conditional"); case SEQNC: t = t2; case COMMA: case LOGAND: case LOGOR: *cp++ = block(op, t, NULL, NULL, p1, p2); return; case CALL: if ((t1&XTYPE) != FUNC) error("Call of non-function"); *cp++ = block(CALL,decref(t1),p1->subsp,p1->strp,p1,p2); return; case STAR: if (p1->op==AMPER ) { *cp++ = p1->tr1; return; } if ((t1&XTYPE) == FUNC) error("Illegal indirection"); *cp++ = block(STAR, decref(t1), p1->subsp, p1->strp, p1); return; case AMPER: if (p1->op==STAR) { *cp++ = p1->tr1; return; } if (p1->op==NAME) { *cp++ = block(op,incref(t1),p1->subsp,p1->strp,p1); return; } error("Illegal lvalue"); break; /* * a.b goes to (&a)->b */ case DOT: *cp++ = p1; build(AMPER); p1 = *--cp; /* * In a->b, a is given the type ptr-to-structure element; * then the offset is added in without conversion; * then * is tacked on to access the member. */ case ARROW: if (p2->op!=NAME || p2->tr1->hclass!=MOS) error("Illegal structure ref"); t = incref(t2); chkw(p1, -1);  setype(p1, t, p2); *cp++ = block(PLUS,t,p2->subsp,p2->strp,p1,cblock(p2->tr1->hoffset)); build(STAR); if (p2->tr1->hflag&FFIELD) *cp++ = block(FSEL,INT,NULL,NULL,*--cp,p2->tr1->hstrp); return; } if ((dope&LVALUE)!=0) chklval(p1); if ((dope&LWORD)!=0) chkw(p1, LONG); if ((dope&RWORD)!=0) chkw(p2, LONG); if ((dope&BINARY)==0) { if (op==ITOF) t1 = DOUBLE; else if (op==FTOI) t1 = INT; if (!fold(op, p1, 0)) *cp++ = block(op,t1,p1->subsp,p1->strp,p1); return; } cvn = 0; if (t1==STRUCT || t2==STRUCT) { error("Unimplemented structure operation"); t1 = t2 = INT; } cvn = cvtab[lintyp(t1)][lintyp(t2)]; leftc = (cvn>>4)&017; cvn =& 017; t = leftc? t2:t1; if (dope&ASSGOP) { t = t1; if (op==ASSIGN) { if (cvn==ITP||cvn==PTI) cvn = leftc = 0; else if (cvn==LTP && leftc==0) cvn = LTI; } if (leftc) cvn = leftc; leftc = 0; } else if (op==COLON || op==MAX || op==MIN) { if (t1>=PTR && t1==t2) cvn = 0; if (op!=COLON && (t1>=PTR || t2>=PTR)) op =+ MAXP-MAX; } else if (dope&RELAT) { if (op>=LESSEQ && (t1>=PTR || t2>=PTR)) op =+ LESSEQP-LESSEQ; if (cvn==PTI) cvn = 0; } if (cvn==PTI) { cvn = 0; if (op==MINUS) { t = INT; pcvn++; } else { if (t1!=t2 || t1!=(PTR+CHAR)) cvn = XX; } } if (cvn) { t1 = plength(p1); t2 = plength(p2); if (cvn==XX || (cvn==PTI&&t1!=t2)) error("Illegal conversion"); else if (leftc) p1 = convert(p1, t, cvn, t2); else p2 = convert(p2, t, cvn, t1); } if (dope&RELAT) t = INT; if (t==FLOAT) t = DOUBLE; if (t==CHAR) t = INT; if (fold(op, p1, p2)==0) { p3 = leftc?p2:p1; *cp++ = block(op, t, p3->subsp, p3->strp, p1, p2); } if (pcvn && t1!=(PTR+CHAR)) { p1 = *--cp; *cp++ = convert(p1, 0, PTI, plength(p1->tr1)); } } /* * Generate the appropriate conversion operator. */ struct tnode * convert(p, t, cvn, len) struct tnode *p; { register int op; op = cvntab[cvn]; if (opdope[op]&BINARY) return(block(op, t, NULL, NULL, p, cblock(len))); return(block(op, t, NULL, NULL, p)); } /* * Traverse an expression tree, adjust things * so the types of things in it are consistent * with the view that its top node has * type at. * Used with structure references. */ setype(ap, at, anewp) struct tnode *ap, *anewp; { register struct tnode *p, *newp; register t; p = ap; t = at; newp = anewp; for (;; p = p->tr1) { p->subsp = newp->subsp; p->strp = newp->strp; p->type = t; if (p->op==AMPER) t = decref(t); else if (p->op==STAR) t = incref(t); else if (p->op!=PLUS) break; } } /* * A mention of a function name is turned into * a pointer to that function. */ struct tnode * chkfun(ap) struct tnode *ap; { register struct tnode *p; register int t; p = ap; if (((t = p->type)&XTYPE)==FUNC) return(block(AMPER,incref(t),p->subsp,p->strp,p)); return(p); } /* * A mention of an array is turned into * a pointer to the base of the array. */ struct tnode * disarray(ap) struct tnode *ap; { register int t; register struct tnode *p; p = ap; /* check array & not MOS */ if (((t = p->type)&XTYPE)!=ARRAY || p->op==NAME&&p->tr1->hclass==MOS) return(p); p->subsp++; *cp++ = p; setype(p, decref(t), p); build(AMPER); return(*--cp); } /* * make sure that p is a ptr to a node * with type int or char or 'okt.' * okt might be nonexistent or 'long' * (e.g. for <<). */ chkw(p, okt) struct tnode *p; { register int t; if ((t=p->type)>CHAR && top = op; p->type = t; p->subsp = subs; p->strp = str; p->tr1 = p1; if (opdope[op]&BINARY) p->tr2 = p2; else p->tr2 = NULL; return(p); } nblock(ads) struct hshtab *ads; { register struct hshtab *ds; ds = ads; return(block(NAME, ds->htype, ds->hsubsp, ds->hstrp, ds)); } /* * Generate a block for a constant */ struct cnode * cblock(v) { register struct cnode *p; p = gblock(sizeof(*p)); p->op = CON; p->type = INT; p->subsp = NULL; p->strp = NULL; p->value = v; return(p); } /* * A block for a float or long constant */ struct fnode * fblock(t, string) char *string; { register struct fnode *p; p = gblock(sizeof(*p)); p->op = FCON; p->type = t; p->subsp = NULL; p->strp = NULL; p->cstr = string; return(p); } /* * Assign a block for use in the * expression tree. */ char * gblock(n) { register int *p; p = curbase; if ((curbase =+ n) >= coremax) { if (sbrk(1024) == -1) { error("Out of space"); exit(1); } coremax =+ 1024; } return(p); } /* * Check that a tree can be used as an lvalue. */ chklval(ap) struct tnode *ap; { register struct tnode *p; p = ap; if (p->op==FSEL) p = p->tr1; if (p->op!=NAME && p->op!=STAR) error("Lvalue required"); } /* * reduce some forms of `constant op constant' * to a constant. More of this is done in the next pass * but this is used to allow constant expressions * to be used in switches and array bounds. */ fold(op, ap1, ap2) struct tnode *ap1, *ap2; { register struct tnode *p1; register int v1, v2; p1 = ap1; if (p1->op!=CON || (ap2!=0 && ap2->op!=CON)) return(0); v1 = p1->value; v2 = ap2->value; switch (op) { case PLUS: v1 =+ v2; break; case MINUS: v1 =- v2; break; case TIMES: v1 =* v2; break; case DIVIDE: v1 =/ v2; break; case MOD: v1 =% v2; break; case AND: v1 =& v2; break; case OR: v1 =| v2; break; case EXOR:  v1 =^ v2; break; case NEG: v1 = - v1; break; case COMPL: v1 = ~ v1; break; case LSHIFT: v1 =<< v2; break; case RSHIFT: v1 =>> v2; break; default: return(0); } p1->value = v1; *cp++ = p1; return(1); } /* * Compile an expression expected to have constant value, * for example an array bound or a case value. */ conexp() { register struct tnode *t; initflg++; if (t = tree()) if (t->op != CON) error("Constant required"); initflg--; curbase = funcbase; return(t->value); } ; break; case NEG: v1 = - v1; break; case COMPL: v1 = ~ v1; break; case LSHIFT: v1 =<< v2; break; case RSHIFT: v1 =>> v2; break; default: return(0); } p1->value = v1; *cp++ = p1; return(1); } /* * Compile an expression expected to have constant value, * for example an array bound or a case value. */ conexp() { register struct tnode *t; initflg++; if (t = tree()) if (t->op != CON) error("Constant required"); initflg--; curbase = funcbase; return(t->vL LP w #( $@ 55 6 %[  _F%#  6%d 5 5 @ r eL A! yD_J% u& & ff Je _FE% & &d%#_JE% & &$ & &f Je_F%$% 5 P5  5   5_%3dfe# %  N 5  f % f( Je ?e$ _Pjf& & &  _%4  f z% _P&_r5 %%  5N &&  te5tE5E @55'5%P%% 55 %   u5 9%%]%_%D-5 %!%% 5%> %%c%5 %5 %)5 D-%  3  5%% 2  Nff Te ff Te55 %%5 f z%  5@&@&ff Je ?e %  &  Te?eww @ 5N f& & f& Je wpN& & f& Jew TDBC%#   %$%(w w DE%&& &# Jeww CE%% wee& & %# lhw b@% %D-E whflag =| FNDEL; xdflg = 0; if ((ds->type&XTYPE)==FUNC) { if ((peeksym=symbol())==LBRACE || peeksym==KEYW) { funcblk.type = decref(ds->type); setinit(ds); if (sclass==EXTERN) outcode("BS", SYMDEF, ds->name); cfunc(); return; } if (paraml) error("Inappropriate parameters"); } else if ((peeksym=symbol())==COMMA || peeksym==SEMI) { o = (length(ds)+ALIGN) & ~ALIGN; if (sclass==STATIC) { setinit(ds); outcode("BBSBN", BSS, NLABEL, ds->name, SSPACE, o); } else outcode("BSN", CSPACE, ds->name, o); } else { setinit(ds); if (sclass==EXTERN) outcode("BS", SYMDEF, ds->name); outcode("BBS", DATA, NLABEL, ds->name); cb = funcbase; if ((cinit(nblock(ds), 1)) & ALIGN) outcode("B", EVEN); funcbase = cb; } } while ((o=symbol())==COMMA); if (o==SEMI) return; syntax: if (o==RBRACE) { error("Too many }'s"); peeksym = 0; return; } error("External definition syntax"); errflush(o); statement(0); } /* * Process a function definition. */ cfunc() { register int *cb; outcode("BBS", PROG, RLABEL, funcsym->name); cb = curbase; regvar = 5; declist(ARG); retlab = isn++; if ((peeksym = symbol()) != LBRACE) error("Compound statement required"); statement(1); outcode("BNB", LABEL, retlab, RETRN); curbase = funcbase = cb; blkend(); } /* * Process the initializers for an external definition. */ cinit(anp, flex) struct tnode *anp; { register struct tnode *np; register nel, ninit; int width, isarray, o, brace, realtype, *cb; struct tnode *s; cb = funcbase; funcbase = curbase; np = anp; realtype = np->type; isarray = 0; if ((realtype&XTYPE) == ARRAY) isarray++; else flex = 0; width = length(np); /* * If it's an array, find the number of elements. * temporarily modify to look like kind of thing it's * an array of. */ if (isarray) { np->type = decref(realtype); np->subsp++; if (width==0 && flex==0) error("0-length row: %.8s", np->tr1->name); } nel = ldiv(0, width, length(np)); width = ldiv(0, width, nel); brace = 0; if ((peeksym=symbol())==LBRACE && (isarray || np->type!=STRUCT)) { peeksym = -1; brace++; } ninit = 0; do { if ((o=symbol())==RBRACE) break; peeksym = o; if (o==STRING && realtype==ARRAY+CHAR) { peeksym = -1; putstr(0, flex?10000:nel); ninit =+ nchstr; o = symbol(); break; } else if (np->type==STRUCT) strinit(np); else if ((np->type&ARRAY)==ARRAY || peeksym==LBRACE) cinit(block(NAME,np->type,np->subsp,np->strp,np->tr1), 0); else { initflg++; s = tree(); initflg = 0; *cp++ = np; *cp++ = s; build(ASSIGN); rcexpr(block(INIT, np->type, NULL, NULL, (*--cp)->tr2)); } ninit++; } while ((o=symbol())==COMMA && (ninitnel) { if (flex && nel==0) { np->subsp[-1] = ninit; if ((np->type&XTYPE) == ARRAY) np->subsp[-1] =* np->subsp[0]; } else error("Too many initializers: %.8s", np->tr1->name); nel = ninit; } curbase = funcbase = cb; return(nel*width); } /* * Initialize a structure */ strinit(np) struct tnode *np; { register struct hshtab **mlp; register int o, brace; mlp = np->strp->memlist;  brace = 0; if ((o = symbol()) == LBRACE) brace++; else peeksym = o; do { if ((o=symbol()) == RBRACE) break; peeksym = o; if (*mlp==0) { error("Too many structure initializers"); cinit(nblock(&funcblk), 0); } else cinit(nblock(*mlp++), 0); if (*mlp == &structhole) { outcode("B", EVEN); mlp++; } } while ((o=symbol())==COMMA && (*mlp || brace)); if (*mlp) outcode("BN", SSPACE, np->strp->ssize - (*mlp)->hoffset); outcode("B", EVEN); if (o!=RBRACE || brace==0) peeksym = o; } /* * Mark already initialized */ setinit(anp) struct hshtab *anp; { register struct hshtab *np; np = anp; if (np->hflag&FINIT) error("%s multiply defined", np->name); np->hflag =| FINIT; } /* * Process one statement in a function. */ statement(d) { register o, o1, o2; int o3; struct tnode *np; stmt: switch(o=symbol()) { case EOF: error("Unexpected EOF"); case SEMI: return; case LBRACE: if (d) { if (proflg) outcode("BN", PROFIL, isn++); outcode("B", SAVE); outcode("BN", SETSTK, -blkhed()); } while (!eof) { if ((o=symbol())==RBRACE) return; peeksym = o; statement(0); } error("Missing '}'"); return; case KEYW: switch(cval) { case GOTO: if (o1 = simplegoto()) branch(o1); else dogoto(); goto semi; case RETURN: doret(); goto semi; case IF: np = pexpr(); o2 = 0; if ((o1=symbol())==KEYW) switch (cval) { case GOTO: if (o2=simplegoto()) goto simpif; cbranch(np, o2=isn++, 0); dogoto(); label(o2); goto hardif; case RETURN: if (nextchar()==';') { o2 = retlab; goto simpif; } cbranch(np, o1=isn++, 0); doret(); label(o1); o2++; goto hardif; case BREAK: o2 = brklab; goto simpif; case CONTIN: o2 = contlab; simpif: chconbrk(o2); cbranch(np, o2, 1); hardif: if ((o=symbol())!=SEMI) goto syntax; if ((o1=symbol())==KEYW && cval==ELSE) goto stmt; peeksym = o1; return; } peeksym = o1; cbranch(np, o1=isn++, 0); statement(0); if ((o=symbol())==KEYW && cval==ELSE) { o2 = isn++; branch(o2); label(o1); statement(0); label(o2); return; } peeksym = o; label(o1); return; case WHILE: o1 = contlab; o2 = brklab; label(contlab = isn++); cbranch(pexpr(), brklab=isn++, 0); statement(0); branch(contlab); label(brklab); contlab = o1; brklab = o2; return; case BREAK: chconbrk(brklab); branch(brklab); goto semi;  case CONTIN: chconbrk(contlab); branch(contlab); goto semi; case DO: o1 = contlab; o2 = brklab; contlab = isn++; brklab = isn++; label(o3 = isn++); statement(0); label(contlab); contlab = o1; if ((o=symbol())==KEYW && cval==WHILE) { cbranch(tree(), o3, 1); label(brklab); brklab = o2; goto semi; } goto syntax; case CASE: o1 = conexp(); if ((o=symbol())!=COLON) goto syntax; if (swp==0) { error("Case not in switch"); goto stmt; } if(swp>=swtab+SWSIZ) { error("Switch table overflow"); } else { swp->swlab = isn; (swp++)->swval = o1; label(isn++); } goto stmt; case SWITCH: o1 = brklab; brklab = isn++; np = pexpr(); chkw(np, -1); rcexpr(block(RFORCE,0,NULL,NULL,np)); pswitch(); brklab = o1; return; case DEFAULT: if (swp==0) error("Default not in switch"); if ((o=symbol())!=COLON) goto syntax; label(deflab = isn++); goto stmt; case FOR: o1 = contlab; o2 = brklab; contlab = isn++; brklab = isn++; if (o=forstmt()) goto syntax; label(brklab); contlab = o1; brklab = o2; return; case ELSE: error("Inappropriate 'else'"); statement(0); return; } error("Unknown keyword"); goto syntax; case NAME: if (nextchar()==':') { peekc = 0; o1 = csym; if (o1->hclass>0) { error("Redefinition"); goto stmt; } o1->hclass = STATIC; o1->htype = ARRAY; if (o1->hoffset==0) o1->hoffset = isn++;  label(o1->hoffset); goto stmt; } } peeksym = o; rcexpr(tree()); semi: if ((o=symbol())==SEMI) return; syntax: error("Statement syntax"); errflush(o); } /* * Process a for statement. */ forstmt() { register int l, o, sline; int sline1, *ss; struct tnode *st; if ((o=symbol()) != LPARN) return(o); if ((o=symbol()) != SEMI) { /* init part */ peeksym = o; rcexpr(tree()); if ((o=symbol()) != SEMI) return(o); } label(contlab); if ((o=symbol()) != SEMI) { /* test part */ peeksym = o; cbranch(tree(), brklab, 0); if ((o=symbol()) != SEMI) return(o); } if ((peeksym=symbol()) == RPARN) { /* incr part */ peeksym = -1; statement(0); branch(contlab); return(0); } l = contlab; contlab = isn++; st = tree(); sline = line; if ((o=symbol()) != RPARN) return(o); ss = funcbase; funcbase = curbase; statement(0); sline1 = line; line = sline; label(contlab); rcexpr(st); line = sline1; curbase = funcbase = ss; branch(l); return(0); } /* * A parenthesized expression, * as after "if". */ struct tnode * pexpr() { register o, t; if ((o=symbol())!=LPARN) goto syntax; t = tree(); if ((o=symbol())!=RPARN) goto syntax; return(t); syntax: error("Statement syntax"); errflush(o); return(0); } /* * The switch statement, which involves collecting the * constants and labels for the cases. */ pswitch() { register struct swtab *cswp, *sswp; int dl, swlab; cswp = sswp = swp; if (swp==0) cswp = swp = swtab; branch(swlab=isn++); dl = deflab; deflab = 0; statement(0); branch(brklab); label(swlab); if (deflab==0) deflab = brklab; outcode("BNN", SWIT, deflab, line); for (; cswp < swp; cswp++) outcode("NN", cswp->swlab, cswp->swval); outcode("0"); label(brklab); deflab = dl; swp = sswp; } /* * blkhed is called at the start of each function. * It reads the declarations at the start; * then assigns storage locations for the * parameters (which have been linked into a list, * in order of appearance). * This list is necessary because in * f(a, b) float b; int a; ... * the names are seen before the types. * Also, the routine adjusts structures involved * in some kind of forward-referencing. */ /* * Structure resembling a block for a register variable. */ struct hshtab hreg { REG, 0, 0, NULL, NULL, 0 }; struct tnode areg { NAME, 0, NULL, NULL, &hreg}; blkhed() { register pl; register struct hshtab *cs; autolen = STAUTO; declist(0); pl = STARG; while(paraml) { parame->hoffset = 0; cs = paraml; paraml = paraml->hoffset;  if (cs->htype==FLOAT) cs->htype = DOUBLE; cs->hoffset = pl; if ((cs->htype&XTYPE) == ARRAY) { cs->htype =- (ARRAY-PTR); /* set ptr */ cs->subsp++; /* pop dims */ } pl =+ rlength(cs); if (cs->hclass==REG && (hreg.hoffset=goodreg(cs))>=0) { cmst[0] = &areg; cmst[1] = nblock(cs); cp = &cmst[2]; areg.type = cs->htype; cs->hclass = AUTO; build(ASSIGN); rcexpr(cmst[0]); cs->hoffset = hreg.hoffset; cs->hclass = REG; } else cs->hclass = AUTO; } for (cs=hshtab; csname[0] == '\0') continue; if (cs->hclass == ARG) error("Not an argument: %.8s", cs->name); if (stflg) prste(cs); } outcode("BN", SETREG, regvar); return(autolen); } /* * After a function definition, delete local * symbols; save those that are external. * Also complain about undefineds. */ blkend() { register struct hshtab *cs, *ncs; register i; for (cs=hshtab; cs->name[0] && csname[0]) { if (cs->hclass==0 && (cs->hflag&FNUND)==0) { error("%.8s undefined", cs->name); cs->hflag =| FNUND; } if(cs->hflag&FNDEL) continue; if (cs->hclass!=EXTERN) { cs->name[0] = '\0'; hshused--; cs->hflag =& ~(FNUND|FFIELD); continue; } /* * Now-permanent name; must rehash. */ for (i=0; iname[i]; lookup(); if (csym != cs) { cs->name[0] = '\0'; cs->hflag =& ~(FNUND|FFIELD); hshused--; lookup(); csym->hclass = EXTERN; csym->htype = cs->htype; csym->hoffset = cs->hoffset; csym->hsubsp = cs->hsubsp; csym->hstrp = cs->hstrp; csym->hflag =| cs->hflag&FFIELD | FNDEL; } else cs->hflag =| FNDEL; } while ((cs = (cs<&hshtab[HSHSIZ-1])? ++cs: hshtab) != ncs); } /* * write out special definitions of local symbols for * benefit of the debugger. None of these are used * by the assembler except to save them. */ prste(acs) struct hshtab *acs; { register struct hshtab *cs; register nkind; cs = acs; switch (cs->hclass) { case REG: nkind = RNAME; break; case AUTO: nkind = ANAME; break; case STATIC: nkind = SNAME; break; default: return; } outcode("BSN", nkind, cs->name, cs->hoffset); } /* * In case of error, skip to the next * statement delimiter. */ errflush(ao) { register o; o = ao; while(o>RBRACE) /* ; { } */ o = symbol(); peeksym = o; } e assembler except to save them. */ prste(acs) struct hshtab *acs; { register struct hshtab *cs; register nkind; cs = acs; switch (cs->hclass) { Rw  _8%_875 5 5 Nefefe %  %_% % b 7 7 ~7 zN& f e`_8V7 NE%/ <78%% 7" % e x % 6_8 _{ n 7% %,  E%  e q e Ee  e8 % e  %e q e6 * &  5  w % _z%% 7    6ww e r e  7%  6bp e7L7H w@w <4.,D55 @E% 5  5 N 4e   e   f& %f& %55 7%  %x  n5%_7\%%H '& m. *5h% DJE%% &&&& e &  + 57 ?eeP  & & &h e z5%  _ _ _ %w@ upN %' %  E%&e&Vp^ e   @77up@ww @ %  %+ %   & j &  % E e D%    @G %J % ww D e L ww  $7 y ` _ .  o %r  t %  R%_ 7B 6 8w, _< x   _ _ _ 5 %a Z x 0  f %  * %;  f % x jd f % J%_ :%%,_>"_   f % 6 %%    6 _ 77  7& H& % 6~ v nj_ b Z_R J_B>:8 40. *&5   6  %_ %_ f & % _  %_  _>% e|x t _>hdb ^ 5f N& & & n e $g  %S7  ;_  68 , %:7 ˋ_` ˕   7x t j%  wPw L D%;4 0 &% % %  & % % 6 w 7% 5 %~ 6tnj N wX@7P7Lw D @%  4 .%w    w  75 7  6 N  e & %e- t wjfwbw ^X LH0 @78#3E%e `˥$ 7:N 7(˕ P  ˕˕  ˥e   e%ti5 %bw^w Z%e  [̋ e 8 G̥ 4 < `2 % 7!+4  0000EUp%e wjw fD   xZ&e G ew0w D %7 w4^ B, :   V bF <Illegal storage classBSInappropriate parametersBBSBNBSNBSBBSBToo many }'sExternal definition syntaxBBSCompound statement requiredBNB0-length row: %.8sBNToo many initializers: %.8sToo many structure initializersBBNB%s multiply definedUnexpected EOFBNBBNMissing '}'Case not in switchSwitch table overflowDefault not in switchInappropriate 'else'Unknown keywordRedefinitionStatement syntaxStatement syntaxBNNNN0Not an argument: %.8sBN%.8s undefinedBSNI()98x)(YY((IiX(YiIYiYx(8 iiyyyyyy(YiI(I(I(9   H XyHXHH XXXH XXXHX(Xx(((y)(IXH IYiYIIXIYiI(I  XIXI X9))y)h(h Ihh(YH)Y)hhII_cvtab _filenam @_opdope _ctab _symbuf _hshused _hshtab _cp _cmst P_isn _swtab _swp _contlab _brklab _retlab _deflab _autolen _peeksym _peekc _eof _line _funcbas _curbase _coremax _defsym _funcsym _xdflg _proflg _stflg _csym _cval _lcval _nchstr _nerror _paraml _parame _strflg _mosflg _initflg _inhdr _obuf _sbuf _regvar _bitoffs _funcblk _cvntab _numbuf @_memlist _nmems _structh _extdef"~extdefcsv sclassotypestrpcbds_symbol L18_getkeyw L2bL3L8zL5b_error _decl1 L9L10000L10 _decref _setinit" L11L12x_outcode _cfunc"<L6L14{L100012L16_length L17pL18L20L22L23L24_nblock _cinit"L25L26L27$L28L29_errflus"_stateme"6cret ~cfunc<cbL31_declist L32L33L34_blkend" ~cinitanpnelosflexisarraycbbracenpninitwidthrealtypeL36L37L38:L40_ldiv L41L10002L44L43L45L10003L10004_putstr L47_strinit"DL46L10005L49*_block _tree _build _rcexpr L10007L51L52L53L54,L56L58*L59 ~strinitDmlpobracenpL61fL65jL64L66L67%L20004L63L70EL71L72GL73JL10009L60~setinit anpnpL76,L77LL10012L1064L109^L103L111L112L10014 L97L101L102 L115BL131, L126 L120: L116L117L118L127 L130 L10016$L10017.L82VL78 L85bL94L134F L80 ~stateme6doo1o2o3npL79>L10018NL83`L20007ZL91L87L88oL89r_blkhed" L90tL20006L93wL95< _simpleg L98L20008_branch L100 _dogoto _doret _pexpr" L107_cbranch _label L108_nextcha L110n_chconbr L113 L10010L114:L200092L20013_conexp L121h L122L20014` L20019\ L124L20016 L20017 _chkw _pswitch" L128 L129_forstmt" L132L133L136d L137L138~ L139~forstmt lossslinestsline1L141 L20020 L140> L20022 L142 L144B L20024( L200268 ~pexpr otL149 L148 L150~pswitch cswpsswpdlswlabL152 L153L L154L155z L20028f L158L159_hreg#<_areg#N~blkhed csplL161L L20030 L163 L164 _rlength L165H _goodreg L20032V L169~ L170r L171_prste"L1735~blkend ncsicsL175 L20034 L176 L180 L178zL182 L1838L184L20036_lookup L188vL10019L10020L10022ZL194L190L195L193~prsteacscsnkindL191L197G~errflusoaoL199L20038 _rlength L165H _goodreg L20032V L169~ L170r L171_prste"L1735~blkend ncsicsL175 L20034 L176 L180 L178zL182 L1838L184L20036_lookup L188vL10019L10020L10022ZL194# /* * C compiler, phase 1 * * * Handles processing of declarations, * except for top-level processing of * externals. */ #include "c0.h" /* * Process a sequence of declaration statements */ declist(sclass) { register sc, offset; struct str *strp; int type; offset = 0; sc = sclass; while (getkeywords(&sclass, &type, &strp)) { offset = declare(sclass, type, offset, strp); sclass = sc; } return(offset+align(INT, offset, 0)); } /* * Read the keywords introducing a declaration statement * Store back the storage class, type, and structure descriptor. */ getkeywords(scptr, tptr, strptr) int *scptr, *tptr; struct str **strptr; { register skw, tkw, longf; int o, isadecl, ismos; isadecl = 0; longf = 0; *strptr = NULL; tkw = -1; skw = *scptr; ismos = skw==MOS; for (;;) { mosflg = ismos; switch ((o=symbol())==KEYW? cval: -1) { case AUTO: case STATIC: case EXTERN: case REG: if (skw && skw!=cval && (skw!=ARG || cval!=REG)) error("Conflict in storage class");  skw = cval; break; case LONG: longf++; break; case STRUCT: *strptr = strdec(ismos); cval = STRUCT; case INT: case CHAR: case FLOAT: case DOUBLE: if (tkw>=0) error("Type clash"); tkw = cval; break; default: peeksym = o; if (isadecl==0) return(0); if (tkw<0) tkw = INT; if (skw==0) skw = xdflg? EXTERN: AUTO; if (longf) { if (tkw==FLOAT) tkw = DOUBLE; else if (tkw==INT) tkw = LONG; else error("Misplaced 'long'"); } *scptr = skw; *tptr = tkw; return(1); } isadecl++; } } /* * Process a structure declaration; a subroutine * of getkeywords. */ struct str * strdec(mosf) { register elsize, o; register struct hshtab *ssym; int savebits; struct hshtab **savememlist; int savenmems; struct str *strp; struct hshtab *ds; struct hshtab *mems[NMEMS]; mosflg = 1; ssym = 0; if ((o=symbol())==NAME) { ssym = csym; if (ssym->hclass==0) { ssym->hclass = STRTAG; ssym->strp = gblock(sizeof(*strp)); funcbase = curbase; ssym->strp->ssize = 0; ssym->strp->memlist = NULL; } if (ssym->hclass != STRTAG) redec(); strp = ssym->strp; mosflg = mosf; o = symbol(); } else { strp = gblock(sizeof(*strp)); funcbase = curbase; strp->ssize = 0; strp->memlist = NULL; } mosflg = 0; if (o != LBRACE) { if (ssym==0) goto syntax; if (ssym->hclass!=STRTAG) error("Bad structure name"); peeksym = o; } else { ds = defsym; mosflg = 0; savebits = bitoffs; savememlist = memlist; savenmems = nmems; memlist = mems; nmems = 2; bitoffs = 0; elsize = declist(MOS); bitoffs = savebits; defsym = ds; if (strp->ssize) error("%.8s redeclared", ssym->name); strp->ssize = elsize; *memlist++ = NULL; strp->memlist = gblock((memlist-mems)*sizeof(*memlist)); funcbase = curbase; for (o=0; &mems[o] != memlist; o++) strp->memlist[o] = mems[o]; memlist = savememlist; nmems = savenmems; if ((o = symbol()) != RBRACE) goto syntax; } return(strp); syntax: decsyn(o); return(0); } /* * Process a comma-separated list of declarators */ declare(askw, tkw, offset, strp) struct str *strp; { register int o; register int skw; skw = askw; do { offset =+ decl1(skw, tkw, offset, strp); } while ((o=symbol()) == COMMA); if (o!=SEMI && (o!=RPARN || skw!=ARG1)) decsyn(o); return(offset); } /* * Process a single declarator */ decl1(askw, tkw, offset, strp) struct str *strp; { int t1, chkoff, a, elsize; register int type, skw; register struct hshtab *dsym; struct tdim dim; struct field *fldp; int *dp; skw = askw; chkoff = 0; mosflg = skw==MOS; dim.rank = 0; if ((peeksym=symbol())==SEMI || peeksym==RPARN) return(0); /* * Filler field */ if (peeksym==COLON && skw==MOS) { peeksym = -1; t1 = conexp(); elsize = align(tkw, offset, t1); bitoffs =+ t1; return(elsize); } if ((t1=getype(&dim)) < 0) goto syntax; type = 0; do type = type<>TYLEN) & XTYPE)!=0); type =| tkw; dsym = defsym; if (dim.rank == 0) dsym->subsp = NULL; else { dp = gblock(dim.rank*sizeof(dim.rank)); funcbase = curbase; for (a=0; ahtype&XTYPE) == ARRAY && dsym->subsp[a] && t1!=dsym->subsp[a]) redec(); } dsym->subsp = dp; } if ((type&XTYPE) == FUNC) { if (skw==AUTO) skw = EXTERN; if (skw!=EXTERN) error("Bad func. storage class"); } if (!(dsym->hclass==0 || ((skw==ARG||skw==REG) && dsym->hclass==ARG1) || (skw==EXTERN && dsym->hclass==EXTERN && dsym->htype==type))) if (skw==MOS && dsym->hclass==MOS && dsym->htype==type) chkoff = 1; else { redec(); goto syntax; } if (dsym->hclass && (dsym->htype&TYPE)==STRUCT && tkw==STRUCT) if (dsym->strp != strp) { error("Warning: structure redeclaration"); nerror--; } dsym->htype = type; if (strp) dsym->strp = strp; if (skw==ARG1) { if (paraml==0) paraml = dsym; else parame->hoffset = dsym; parame = dsym; } elsize = 0; if (skw==MOS) {  elsize = length(dsym); if ((peeksym = symbol())==COLON) { elsize = 0; peeksym = -1; t1 = conexp(); a = align(type, offset, t1); if (dsym->hflag&FFIELD) { if (dsym->hstrp->bitoffs!=bitoffs || dsym->hstrp->flen!=t1) redec(); } else { dsym->hstrp = gblock(sizeof(*fldp)); funcbase = curbase; } dsym->hflag =| FFIELD; dsym->hstrp->bitoffs = bitoffs; dsym->hstrp->flen = t1; bitoffs =+ t1; } else a = align(type, offset, 0); elsize =+ a; offset =+ a; if (++nmems >= NMEMS) { error("Too many structure members"); nmems =- NMEMS/2; memlist =- NMEMS/2; } if (a) *memlist++ = &structhole; if (chkoff && dsym->hoffset != offset) redec(); dsym->hoffset = offset; *memlist++ = dsym; } if (skw==REG && dsym->hclass!=ARG1) if ((dsym->hoffset = goodreg(dsym)) < 0) skw = AUTO; if (skw==AUTO) { /* if (STAUTO < 0) { */ autolen =- rlength(dsym); dsym->hoffset = autolen; /* } else { */ /* dsym->hoffset = autolen; */ /* autolen =+ rlength(dsym); */ /* } */ } else if (skw==STATIC) { dsym->hoffset = isn; outcode("BBNBNB", BSS, LABEL, isn++, SSPACE, rlength(dsym), PROG); } dsym->hclass = skw; syntax: return(elsize); } /* * Read a declarator and get the implied type */ getype(adimp) struct tdim *adimp; { int type; register int o; register struct hshtab *ds; register struct tdim *dimp; ds = defsym; dimp = adimp; switch(o=symbol()) { case TIMES: return(getype(dimp)<rank>=5) { error("Rank too large"); dimp->rank = 4; } if ((o=symbol()) != RBRACK) { peeksym = o; cval = conexp(); if ((o=symbol())!=RBRACK) goto syntax; } else { if (dimp->rank!=0) error("Null dimension"); cval = 0; } for (o=0; o < dimp->rank; o++) dimp->dimens[o] =* cval; dimp->dimens[dimp->rank++] = cval; type = type<offset) bitoffs = 0; } if (flen) { if (type==INT) { if (flen > NBPW) error(ftl); if (flen+bitoffs > NBPW) { bitoffs = 0; a =+ NCPW; } } else if (type==CHAR) { if (flen > NBPC) error(ftl); if (flen+bitoffs > NBPC) { bitoffs = 0; a =+ 1; } } else error("Bad type for field"); } return(a-offset); } /* * Complain about syntax error in declaration */ decsyn(o) { error("Declaration syntax"); errflush(o); } /* * Complain about a redeclaration */ redec() { error("%.8s redeclared", defsym->name); } /* * Determine if a variable is suitable for storage in * a register; if so return the register number */ goodreg(hp) struct hshtab *hp; { int type; type = hp->htype; if ((type&TYPE)>CHAR && (type&XTYPE)==0 || (type&XTYPE)>PTR || regvar<3) return(-1); return(--regvar); } return(a-offset); } /* * Complain about syntax error in declaration */ decsyn(o) { error("Declaration syntax"); errflush(o); } /* * Complain about a redeclaration */ redec() { error("%.8s redeclared", defsym->name); } /* * Determine if a variable is suitable for storage in * a register; if so return the register number */ goodreg(hp) struct hshtab *hp; { int type; type = hp->htype; if ((type&TYPE)>CHAR t L w  DNff e5Nefefe Z%  & .%`ww 5  = D%  5wt p5%b / xt  -H %%: ,  N `=  w  w      %   =w  %$ʋʕ 2hf: 0 ʥ \wD @ 5,*= @0 7 % _ʥ n7 @e77  ww e  =? eAe@@ r  A1db @ @` AaH  @ae-6w.w( $%@w  w CN ff De5` % % %% @ww C5 %  75 7%% % r n5ff .%5wmP@wH%BNe 5 tAE@P@t55D] 2 ?@  55 *@ @mA AaAH@5E%@ l @ lH-  u-rE% %  %  ʋ%%ʥ% ʥ 2! % 1ʥ .2!+ʋE%% r-  2 r %  _5 % _^ 5 7%;5  |5f& .%5 -Vz-  R  242$zwm  f& .%5umum % : @ e r- re% ʥ & 2 %  7vr% d X &L HpU e ʐ_w * $B  7 y tU_5 i x 7  & &  e  %g@tUB%\  % 7| x7t p% D k 7 V  f`eBVp^ " `(@tU5  7@w 5 % w BDCz e r`7  E%% ED-7 v . %N mX%7 Ne%%N m,%7 "  @w w  N ww e  ww @5@E%5 @E%%w b* "Conflict in storage classType clashMisplaced 'long'Bad structure name%.8s redeclaredBad func. storage classWarning: structure redeclarationToo many structure membersBBNBNBRank too largeNull dimensionField too longBad type for fieldDeclaration syntax%.8s redeclaredIIY9IY9XiYY9XiYYY  XiY 9I9IY9Y XiY))99 9Y XiY       I999Y 999II8II_cvtab _filenam @_opdope _ctab _symbuf _hshused _hshtab _cp _cmst P_isn _swtab _swp _contlab _brklab _retlab _deflab _autolen _peeksym _peekc _eof _line _funcbas _curbase _coremax _defsym _funcsym _xdflg _proflg _stflg _csym _cval _lcval _nchstr _nerror _paraml _parame _strflg _mosflg _initflg _inhdr _obuf _sbuf _regvar _bitoffs _funcblk _cvntab _numbuf @_memlist _nmems _structh _declist"~declistcsv sclassoffsettypestrpscL2,L20001_declare"_getkeyw"Z_align".cret L10008t L20L16L23L15L12~getkeywZskwtkwstrptroisadecltptrlongfismosscptrL10000~L10001L5_symbol L10002L8L13L10004L14 _error L7_strdec"`L21L22 L24L4L25L260L10005*L10006.L27RL28@L30JL32 ~strdec`elsizeomemsmosfstrpssymdssavememlsavenmemsavebitsL34L35_gblock L36_redec" L37L38L39L40L41 L42L43dL44 L45L20003L33_decsyn"~declaretkwskwoffsetoaskwstrp L51_decl1"DL52<L100096~decl1Ddimchkofftkwskwoffsetelsizeafldpaskwdsymtypestrp t1dpL10010^L10011bL10012~L54L53L20005L55_conexp L20008_getype"L59L60 L61L62zL20007&L64vL66L67L69 L70L10014L10013L10015L71<L73L75 L76*L77PL78DL79LL80^_length L81L82L10016L84L85L86*L87: L88<L89NL90z_goodreg"& L92_rlength L93L95U _outcode L10018 L109bL104L106L10020 L10021 L100L103 L99L101"~getypeodimptypedsadimpL10022L96L102L20012L107HL108TL20015L110tL111\ L112L113L114L115k L116L20010~align.ftloffsetatflentypeaflenL120z L122hL20017`_decref L124L126L127L128L131L132L135 ~decsynoL137 _errflus ~redec L139 ~goodreg& typehpL10024L L10023b L141j L140f HL108TL20015L110tL111\ L112L113L114L115k L116L20010~align.ftloffsetatflentypeaflenL120z L122hL20017`_decref L124L126L127L128L131L132L135 ~decsynoL137 _errflus ~redec L139 ~goodreg& typehpL100# /* * C compiler * * */ #include "c0.h" /* * Reduce the degree-of-reference by one. * e.g. turn "ptr-to-int" into "int". */ decref(at) { register t; t = at; if ((t & ~TYPE) == 0) { error("Illegal indirection"); return(t); } return((t>>TYLEN) & ~TYPE | t&TYPE); } /* * Increase the degree of reference by * one; e.g. turn "int" to "ptr-to-int". */ incref(t) { return(((t&~TYPE)<op==INIT && tp->tr1->op==CON) { if (tp->type==CHAR) { outcode("B1N0", BDATA, tp->tr1->value); return; } else if (tp->type==INT) { outcode("BN", SINIT, tp->tr1->value); return; } } treeout(tp); outcode("BN", EXPR, line); }  treeout(atp) struct tnode *atp; { register struct tnode *tp; register struct hshtab *hp; if ((tp = atp) == 0) { outcode("B", NULLOP); return; } switch(tp->op) { case NAME: hp = tp->tr1; outcode("BNN", NAME, hp->hclass==0?STATIC:hp->hclass, tp->type); if (hp->hclass==EXTERN) outcode("S", hp->name); else outcode("N", hp->hoffset); return; case LCON: outcode("BNNN", tp->op, tp->type, tp->lvalue); return; case CON: outcode("BNN", tp->op, tp->type, tp->value); return; case FCON: outcode("BNF", tp->op, tp->type, tp->cstr); return; case STRING: outcode("BNNN", NAME, STATIC, tp->type, tp->tr1); return; case FSEL: treeout(tp->tr1); outcode("BNNN",tp->op,tp->type,tp->tr2->bitoffs,tp->tr2->flen); return; default: treeout(tp->tr1); if (opdope[tp->op]&BINARY) treeout(tp->tr2); outcode("BN", tp->op, tp->type); return; } } /* * Generate a branch */ branch(lab) { outcode("BN", BRANCH, lab); } /* * Generate a label */ label(l) { outcode("BN", LABEL, l); } /* * ap is a tree node whose type * is some kind of pointer; return the size of the object * to which the pointer points. */ plength(ap) struct tname *ap; { register t, l; register struct tnode *p; p = ap; if (p==0 || ((t=p->type)&~TYPE) == 0) /* not a reference */ return(1); p->type = decref(t); l = length(p); p->type = t; return(l); } /* * return the number of bytes in the object * whose tree node is acs. */ length(acs) struct tnode *acs; { register t, n; register struct tnode *cs; cs = acs; t = cs->type; n = 1; while ((t&XTYPE) == ARRAY) { t = decref(t); n = *cs->subsp; } if ((t&~TYPE)==FUNC) return(0); if (t>=PTR) return(SZPTR*n); switch(t&TYPE) { case INT: return(SZINT*n); case CHAR: return(n); case FLOAT: return(SZFLOAT*n); case LONG: return(SZLONG*n); case DOUBLE: return(SZDOUB*n); case STRUCT: if ((t = cs->strp->ssize) == 0) error("Undefined structure"); return(n * t); } error("Compiler error (length)"); return(0); }  /* * The number of bytes in an object, rounded up to a word. */ rlength(cs) struct tnode *cs; { return((length(cs)+ALIGN) & ~ALIGN); } /* * After an "if (...) goto", look to see if the transfer * is to a simple label. */ simplegoto() { register struct hshtab *csp; if ((peeksym=symbol())==NAME && nextchar()==';') { csp = csym; if (csp->hclass==0 && csp->htype==0) { csp->htype = ARRAY; if (csp->hoffset==0) csp->hoffset = isn++; } if ((csp->hclass==0||csp->hclass==STATIC) && csp->htype==ARRAY) { peeksym = -1; return(csp->hoffset); } } return(0); } /* * Return the next non-white-space character */ nextchar() { while (spnextchar()==' ') peekc = 0; return(peekc); } /* * Return the next character, translating all white space * to blank and handling line-ends. */ spnextchar() { register c; if ((c = peekc)==0) c = getchar(); if (c=='\t' || c=='\014') /* FF */ c = ' '; else if (c=='\n') { c = ' '; if (inhdr==0) line++; inhdr = 0; } else if (c=='\001') { /* SOH, insert marker */ inhdr++; c = ' '; } peekc = c; return(c); } /* * is a break or continue legal? */ chconbrk(l) { if (l==0) error("Break/continue error"); } /* * The goto statement. */ dogoto() { register struct tnode *np; *cp++ = tree(); build(STAR); chkw(np = *--cp, -1); rcexpr(block(JUMP,0,NULL,NULL,np)); } /* * The return statement, which has to convert * the returned object to the function's type. */ doret() { register struct tnode *t; if (nextchar() != ';') { t = tree(); *cp++ = &funcblk; *cp++ = t; build(ASSIGN); cp[-1] = cp[-1]->tr2; build(RFORCE); rcexpr(*--cp); } branch(retlab); } /* * Write a character on the error output. */ putchar(c) { write(1, &c, 1); } /* * Coded output: * B: beginning of line; an operator * N: a number * S: a symbol (external) * 1: number 1 * 0: number 0 */ outcode(s, a) char *s; { register *ap, *bufp; int n; register char *np; bufp = obuf; if (strflg) bufp = sbuf; ap = &a; for (;;) switch(*s++) { case 'B': putw(*ap++ | (0376<<8), bufp); continue; case 'N': putw(*ap++, bufp); continue; case 'F': n = 1000; goto str; case 'S': n = NCPS; str: np = *ap++; while (n-- && *np) { putc(*np++, bufp); } putc(0, bufp); continue; case '1': putw(1, bufp); continue; case '0': putw(0, bufp); continue; case '\0': return; default: error("Botch in outcode"); } } t n; register char *np; bufp = obuf; if (strflg) bufp = sbuf; ap = &a; for (;;) swi^ w D5 wtEE@Pw @EtAE@PUww N ffg eww ~D%h%%     0 %ww Dn  d x^ˋ & e˥ e & &&& he 2&& e&&&&    &&& ew8    5 & %w No %ww Np %ww B5w 2 l2w B E%E%   x~tt  Dp@w"%E ރ w N l Eww 7%' N%;"̋    ̥̋ %w w 7 % twpw lh b% % %  F @7 <% 0 7(w"w  & w w  ?e$ & & & & f e ~ww *%;% e?eP Ap n nj ~b wZw Vfe %w>w :  0De@ 7 y&U &ʋ & @ & & ; w`xD01BFNSZJB PIllegal indirectionBNNNB1N0BNBNBBNNSNBNNNBNNBNFBNNNBNNNBNBNBNUndefined structureCompiler error (length)Break/continue errorBotch in outcodeIIIIIII(IIIIII I))I) yIyy)II yy yy I yyyy y yyI8 II _cvtab _filenam @_opdope _ctab _symbuf _hshused _hshtab _cp _cmst P_isn _swtab _swp _contlab _brklab _retlab _deflab _autolen _peeksym _peekc _eof _line _funcbas _curbase _coremax _defsym _funcsym _xdflg _proflg _stflg _csym _cval _lcval _nchstr _nerror _paraml _parame _strflg _mosflg _initflg _inhdr _obuf _sbuf _regvar _bitoffs _funcblk _cvntab _numbuf @_memlist _nmems _structh _decref"~decrefcsv tatL2L3_error L1cret _incref"0~incref0t_cbranch"R~cbranchRlbltcond_treeout"L6_outcode"_rcexpr"~~rcexpr~atptpL8L9L10L20001L13L14L10003^L34L36L20L28`L32L30xL26D~treeoutatphptpL16L17L20003L15L20005L10000L10001L21L22:L23L25L27L29L20009nL31L33L20007L35L37L38_branch"~branchlabL40_label"~labellL42_plength"6~plength6lptapL10004JL44RL43N_length"lL10006~L20013L53L54L56L57L50~lengthlacsntcsL46L20011~L48L20017L45L20016L58L59L60_rlength"~rlengthcs_simpleg"~simplegcsp_symbol L63p_nextcha"tL64PL10007ZL62l~nextchatL68~L20020z_spnextc"~spnextccL71_getchar L20021L74L75L73_chconbr"~chconbrlL78L80&_dogoto"~dogotonp_tree _build _chkw _block _doret"B~doretBtL83_putchar"~putcharc_write L10010L10011L85ZL99JL98BL91L93 L92L95L101P~outcodeansbufpapnpL86L87L10012L20025_putw L20026L94L96,L20023L978_putc L102;otonp_tree _build _chkw _block _doret"B~doretBtL83_putchar"~putcharc_write L10010L10011L85ZL99# #include "c0.h" /* * info on operators: * 01-- is binary operator * 02-- left (or only) operand must be lvalue * 04-- is relational operator * 010-- is assignment-type operator * 020-- non-float req. on left * 040-- non-float req. on right * 0100-- is commutative * 0200-- is right, not left-associative * 0400-- is leaf of tree * *0XX000-- XX is priority of operator */ int opdope[] { 000000, /* EOF */ 000000, /* ; */ 000000, /* { */ 000000, /* } */ 036000, /* [ */ 002000, /* ] */ 036000, /* ( */ 002000, /* ) */ 014201, /* : */ 007001, /* , */ 000001, /* field selection */ 000000, /* 11 */ 000000, /* 12 */ 000001, /* integer->ptr */ 000001, /* ptr->integer */ 000001, /* long->ptr */ 000000, /* 16 */ 000000, /* 17 */ 000000, /* 18 */ 000000, /* 19 */ 000400, /* name */ 000400, /* short constant */ 000400, /* string */ 000400, /* float */ 000400, /* double */ 000400, /* long constant */ 000400, /* long constant <= 16 bits */ 000000, /* 27 */ 000000, /* 28 */ 000000, /* 29 */ 034203, /* ++pre */ 034203, /* --pre */ 034203, /* ++post */ 034203, /* --post */ 034220, /* !un */ 034202, /* &un */ 034220, /* *un */ 034200, /* -un */ 034220, /* ~un */ 036001, /* . (structure reference) */ 030101, /* + */ 030001, /* - */ 032101, /* * */ 032001, /* / */ 032001, /* % */ 026061, /* >> */ 026061, /* << */ 020161, /* & */ 017161, /* | */ 017161, /* ^ */ 036001, /* -> */ 000000, /* int -> double */ 000000, /* double -> int */ 016001, /* && */ 015001, /* || */ 030001, /* &~ */ 000000, /* 56 */ 000000, /* 57 */ 000000, /* 58 */ 000000, /* 59 */ 022005, /* == */ 022005, /* != */ 024005, /* <= */ 024005, /* < */ 024005, /* >= */ 024005, /* > */ 024005, /*

p */ 024005, /* >=p */ 012213, /* =+ */ 012213, /* =- */ 012213, /* =* */ 012213, /* =/ */ 012213, /* =% */ 012253, /* =>> */ 012253, /* =<< */ 012253, /* =& */ 012253, /* =| */ 012253, /* =^ */ 012213, /* = */ 000000, /* 81 */ 000000, /* 82 */ 000000, /* 83 */ 000000, /* 84 */ 000000, /* 85 */ 000000, /* 86 */ 000000, /* 87 */ 000000, /* 88 */ 000000, /* 89 */ 014201, /* ? */ 034200, /* sizeof */ 000000, /* 92 */ 021101, /* min */ 021101, /* minp */ 021101, /* max */ 021101, /* maxp */ 007001, /* , */ 000000, /* 98 */ 000000, /* 99 */ 036001, /* call */ 036001, /* mcall */ 000000, /* goto */ 000000, /* jump cond */ 000000, /* branch cond */ 000000, /* 105 */ 000000, /* 106 */ 000000, /* 107 */ 000000, /* 108 */ 000000, /* 109 */ 000000 /* force r0 */ }; /* * conversion table: * FTI: float (or double) to integer * ITF: integer to float * ITP: integer to pointer * ITL: integer to long * LTI: long to integer * LTF: long to float * FTL: float to long * PTI: pointer to integer * LTP: long to ptr (ptr[long]) * XX: usually illegal * When FTI, LTI, FTL are added in they specify * that it is the left operand that should be converted. * For + this is done and the conversion is turned back into * ITF, ITL, LTF. * For = however the left operand can't be converted * and the specified conversion is applied to the rhs. */ char cvtab[4][4] { /* int double long ptr */ /* int */ 0, (FTI<<4)+ITF, (LTI<<4)+ITL, (ITP<<4)+ITP, /* double */ ITF, 0, LTF, XX, /* long */ ITL, (FTL<<4)+LTF, 0, (LTP<<4)+LTP, /* ptr */ ITP, XX, LTP, PTI, }; /* * relate conversion numbers to operators */ char cvntab[] { 0, ITOF, ITOL, LTOF, ITOP, PTOI, FTOI, LTOI, FTOL, LTOP, }; /* * character type table */ char ctab[] { EOF, INSERT, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, SPACE, NEWLN, UNKN, SPACE, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, SPACE, EXCLA, DQUOTE, SHARP, UNKN, MOD, AND, SQUOTE, LPARN, RPARN, TIMES, PLUS, COMMA, MINUS, PERIOD, DIVIDE, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, COLON, SEMI, LESS, ASSIGN, GREAT, QUEST, UNKN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LBRACK, BSLASH, RBRACK, EXOR, LETTER, UNKN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LBRACE, OR, RBRACE, COMPL, UNKN }; T, UNKN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETxX<<888888888op)==0) return(0); dope = opdope[op]; if ((dope&LEAF) == 0) p1 = tree->tr1; else p1 = tree; t1 = p1->type; d1 = dcalc(p1, nrleft); if ((dope&BINARY)!=0) { p2 = tree->tr2; /* * If a subtree starts off with a conversion operator, * try for a match with the conversion eliminated. * E.g. int = double can be done without generating * the converted int in a register by * movf double,fr0; movfi fr0,int . */ if(opdope[p1->op]&CNVRT && (opdope[p2->op]&CNVRT)==0) { tree->tr1 = p1->tr1; if (opt = match(tree, table, nrleft)) return(opt); tree->tr1 = p1; } else if (opdope[p2->op]&CNVRT && (opdope[p1->op]&CNVRT)==0) { tree->tr2 = p2->tr1; if (opt = match(tree, table, nrleft)) return(opt); tree->tr2 = p2; } t2 = p2->type; d2 = dcalc(p2, nrleft); } for (; table->op!=op; table++)  if (table->op==0) return(0); for (opt = table->tabp; opt->tabdeg1!=0; opt++) { if (d1 > (opt->tabdeg1&077) || (opt->tabdeg1 >= 0100 && (p1->op != STAR))) continue; if (notcompat(p1, opt->tabtyp1, op)) { continue; } if ((opdope[op]&BINARY)!=0 && p2!=0) { if (d2 > (opt->tabdeg2&077) || (opt->tabdeg2 >= 0100) && (p2->op != STAR) ) continue; if (notcompat(p2,opt->tabtyp2, 0)) continue; } return(opt); } return(0); } /* * Given a tree, a code table, and a register, * produce code to evaluate the tree with the appropriate table. * Registers reg and upcan be used. * If there is a value, it is desired that it appear in reg. * The routine returns the register in which the value actually appears. * This routine must work or there is an error. * If the table called for is cctab, sptab, or efftab, * and tree can't be done using the called-for table, * another try is made. * If the tree can't be compiled using cctab, regtab is * used and a "tst" instruction is produced. * If the tree can't be compiled using sptab, * regtab is used and the register is pushed on the stack. * If the tree can't be compiled using efftab, * just use regtab. * Regtab must succeed or an "op not found" error results. * * A number of special cases are recognized, and * there is an interaction with the optimizer routines. */ rcexpr(atree, atable, reg) struct tnode *atree; struct table *atable; { register r; int modf, nargs, recurf; register struct tnode *tree; register struct table *table; table = atable; recurf = 0; if (reg<0) { recurf++; reg = ~reg; if (reg>=020) { reg =- 020; recurf++; } } again: if((tree=atree)==0) return(0); /* * fieldselect(...) : in efftab mode, * ignore the select, otherwise * do the shift and mask. */ if (tree->op == FSELT) { if (table==efftab) atree = tree = tree->tr1; else { tree->op = FSEL; atree = tree = optim(tree); } } switch (tree->op) { /* * An initializing expression */ case INIT: tree = optim(tree); doinit(tree->type, tree->tr1); return(0); /* * Put the value of an expression in r0, * for a switch or a return */ case RFORCE: if((r=rcexpr(tree->tr1, regtab, reg)) != 0) movreg(r, 0, tree->tr1); return(0); /* * sequential execution */ case SEQNC: rcexpr(tree->tr1, efftab, reg); atree = tree = tree->tr2; goto again; /* * In the generated &~ operator, * fiddle things so a PDP-11 "bit" * instruction will be produced when cctab is used. */ case NAND: if (table==cctab) { tree->op = TAND; tree->tr2 = optim(tnode(COMPL, tree->type, tree->tr2)); } break; /* * Handle a subroutine call. It has to be done * here because if cexpr got called twice, the * arguments might be compiled twice. * There is also some fiddling so the * first argument, in favorable circumstances, * goes to (sp) instead of -(sp), reducing * the amount of stack-popping. */ case CALL: r = 0; nargs = 0; modf = 0; if (tree->tr1->op!=NAME) { /* get nargs right */ nargs++; nstack++; } tree = tree->tr2; if(tree->op) { while (tree->op==COMMA) { r =+ comarg(tree->tr2, &modf); tree = tree->tr1; nargs++; } r =+ comarg(tree, &modf); nargs++; } tree = atree; tree->op = CALL2; if (modf && tree->tr1->op==NAME && tree->tr1->class==EXTERN) tree->op = CALL1; cexpr(tree, regtab, reg); popstk(r); nstack =- nargs; if (table==efftab || table==regtab) return(0); r = 0; goto fixup; /* * Longs need special treatment.  */ case ASLSH: case LSHIFT: if (tree->type==LONG) { if (tree->tr2->op==ITOL) tree->tr2 = tree->tr2->tr1; else tree->tr2 = optim(tnode(LTOI,INT,tree->tr2)); if (tree->op==ASLSH) tree->op = ASLSHL; else tree->op = LLSHIFT; } break; /* * Try to change * to shift. */ case TIMES: case ASTIMES: tree = pow2(tree); } /* * Try to find postfix ++ and -- operators that can be * pulled out and done after the rest of the expression */ if (table!=cctab && table!=cregtab && recurf<2 && (opdope[tree->op]&LEAF)==0) { if (r=delay(&atree, table, reg)) { tree = atree; table = efftab; reg = r-1; } } /* * Basically, try to reorder the computation * so reg = x+y is done as reg = x; reg =+ y */ if (recurf==0 && reorder(&atree, table, reg)) { if (table==cctab && atree->op==NAME) return(reg); } tree = atree; if (table==efftab && tree->op==NAME) return(reg); if ((r=cexpr(tree, table, reg))>=0) return(r); if (table!=regtab && (table!=cctab||(opdope[tree->op]&RELAT)==0)) { if((r=cexpr(tree, regtab, reg))>=0) { fixup: modf = isfloat(tree); if (table==sptab || table==lsptab) { if (tree->type==LONG) { printf("mov\tr%d,-(sp)\n",r+1); nstack++; } printf("mov%c r%d,%c(sp)\n", modf, r, table==sptab? '-':0); nstack++; } if (table==cctab) printf("tst%c r%d\n", modf, r); return(r); } } if (tree->type == STRUCT) error("Illegal operation on structure"); else if (tree->op>0 && tree->opop]) error("No code table for op: %s", opntab[tree->op]); else error("No code table for op %d", tree->op); return(reg); } /* * Try to compile the tree with the code table using * registers areg and up. If successful, * return the register where the value actually ended up. * If unsuccessful, return -1. * * Most of the work is the macro-expansion of the * code table. */ cexpr(atree, table, areg) struct tnode *atree; struct table *table; { int c, r; register struct tnode *p, *p1, *tree; struct table *ctable; struct tnode *p2; char *string; int reg, reg1, rreg, flag, opd; char *opt; tree = atree; reg = areg; p1 = tree->tr2; c = tree->op; opd = opdope[c]; /* * When the value of a relational or a logical expression is * desired, more work must be done. */ if ((opd&RELAT||c==LOGAND||c==LOGOR||c==EXCLA) && table!=cctab) { cbranch(tree, c=isn++, 1, reg); rcexpr(&czero, table, reg); branch(isn, 0); label(c); rcexpr(&cone, table, reg); label(isn++); return(reg); } if(c==QUEST) { if (table==cctab) return(-1); cbranch(tree->tr1, c=isn++, 0, reg); flag = nstack; rreg = rcexpr(p1->tr1, table, reg); nstack = flag; branch(r=isn++, 0); label(c); reg = rcexpr(p1->tr2, table, rreg); if (rreg!=reg) movreg(reg, rreg, tree); label(r); return(rreg); } reg = oddreg(tree, reg); reg1 = reg+1; /* * long values take 2 registers. */ if ((tree->type==LONG||opd&RELAT&&tree->tr1->type==LONG) && tree->op!=ITOL) reg1++; /* * Leaves of the expression tree */ if ((r = chkleaf(tree, table, reg)) >= 0) return(r); /* * x + (-1) is better done as x-1. */ if ((tree->op==PLUS||tree->op==ASPLUS) && (p1=tree->tr2)->op == CON && p1->value == -1) { p1->value = 1; tree->op =+ (MINUS-PLUS); } /* * Because of a peculiarity of the PDP11 table * char = *intreg++ and *--intreg cannot go through. */ if (tree->tr1->type==CHAR && tree->tr2->type!=CHAR && (tree->tr2->op==AUTOI||tree->tr2->op==AUTOD)) tree->tr2 = tnode(LOAD, tree->tr2->type, tree->tr2); if (table==cregtab) table = regtab; /* * The following peculiar code depends on the fact that * if you just want the codition codes set, efftab * will generate the right code unless the operator is * postfix ++ or --. Unravelled, if the table is * cctab and the operator is not special, try first * for efftab; if the table isn't, if the operator is, * or the first match fails, try to match * with the table actually asked for. */ r = nreg - reg; if (table!=cctab || c==INCAFT || c==DECAFT || tree->type==LONG || (opt = match(tree, efftab, r)) == 0) if ((opt=match(tree, table, r))==0) return(-1); string = opt->tabstring; p1 = tree->tr1; if (p1->op==FCON && p1->value>0) { printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p1->value, p1->fvalue); p1->value = -p1->value; } p2 = 0; if (opdope[tree->op]&BINARY) { p2 = tree->tr2; if (p2->op==FCON && p2->value>0) { printf(".data\nL%d:%o;%o;%o;%o\n.text\n", p2->value, p2->fvalue); p2->value = -p2->value;  } } loop: /* * The 0200 bit asks for a tab. */ if ((c = *string++) & 0200) { c =& 0177; putchar('\t'); } switch (c) { case '\0': if (!isfloat(tree)) if (tree->op==DIVIDE||tree->op==ASDIV||tree->op==PTOI) reg--; return(reg); /* A1 */ case 'A': p = p1; goto adr; /* A2 */ case 'B': p = p2; goto adr; adr: c = 0; if (*string=='\'') { c = 1; string++; } else if (*string=='+') { c = 2; string++; } pname(p, c); goto loop; /* I */ case 'M': if ((c = *string)=='\'') string++; else c = 0; prins(tree->op, c, instab); goto loop; /* B1 */ case 'C': if ((opd&LEAF) != 0) p = tree; else p = p1; goto pbyte; /* BF */ case 'P': p = tree; goto pb1; /* B2 */ case 'D': p = p2; pbyte: if (p->type==CHAR) putchar('b'); pb1: if (isfloat(p)) putchar('f'); goto loop; /* BE */ case 'L': if (p1->type==CHAR || p2->type==CHAR) putchar('b'); p = tree; goto pb1; /* F */ case 'G': p = p1; flag = 01; goto subtre; /* S */ case 'K': p = p2; flag = 02; goto subtre; /* H */ case 'H': p = tree; flag = 04; subtre: ctable = regtab; if (flag&04) ctable = cregtab; c = *string++ - 'A'; if (*string=='!') { string++; c =| 020; /* force right register */ } if ((c&02)!=0) ctable = sptab; if ((c&04)!=0) ctable = cctab; if ((flag&01) && ctable==regtab && (c&01)==0 && (tree->op==DIVIDE||tree->op==MOD || tree->op==ASDIV||tree->op==ASMOD)) ctable = cregtab; if ((c&01)!=0) { p = p->tr1; if(collcon(p) && ctable!=sptab) { if (p->op==STAR) p = p->tr1; p = p->tr1; } } if (table==lsptab && ctable==sptab) ctable = lsptab; if (c&010) r = reg1; else if (opdope[p->op]&LEAF || p->degree < 2) r = reg; else r = areg; rreg = rcexpr(p, ctable, r); if (ctable!=regtab && ctable!=cregtab) goto loop; if (c&010) { if (c&020 && rreg!=reg1) movreg(rreg, reg1, tree); else reg1 = rreg; } else if (rreg!=reg) if ((c&020)==0 && oddreg(tree, 0)==0 && tree->type!=LONG && (flag&04 || flag&01&&xdcalc(p2,nreg-rreg-1)<=(opt->tabdeg2&077) || flag&02&&xdcalc(p1,nreg-rreg-1)<=(opt->tabdeg1&077))) { reg = rreg; reg1 = rreg+1; } else movreg(rreg, reg, tree); goto loop; /* R */ case 'I': r = reg; if (*string=='-') { string++; r--; } goto preg; /* R1 */ case 'J': r = reg1; preg: if (*string=='+') { string++; r++; } if (r>nreg || r>=4 && tree->type==DOUBLE) error("Register overflow: simplify expression"); printf("r%d", r); goto loop; case '-': /* check -(sp) */ if (*string=='(') { nstack++; if (table!=lsptab) putchar('-'); goto loop; } break; case ')': /* check (sp)+ */ putchar(')'); if (*string=='+') nstack--; goto loop; /* #1 */ case '#': p = p1->tr1; goto nmbr; /* #2 */ case '"': p = p2->tr1; nmbr: if(collcon(p)) { if (p->op==STAR) { printf("*"); p = p->tr1; } if ((p = p->tr2)->op == CON) { if (p->value) psoct(p->value); } else if (p->op==AMPER) pname(p->tr1, 0); } goto loop; /* * Certain adjustments for / % and PTOI */ case 'T': c = reg-1; if (tree->op == PTOI) { printf("bic r%d,r%d\nsbc r%d\n", c,c,c); goto loop; } if (dcalc(p1, 5)>12 && !match(p1, cctab, 10)) printf("tst r%d\n", reg); printf("sxt r%d\n", c); goto loop; case 'V': /* adc sbc, or sxt as required for longs */ switch(tree->op) { case PLUS: case ASPLUS: case INCBEF: case INCAFT: printf("adc"); break; case MINUS: case ASMINUS: case NEG: case DECBEF: case DECAFT: printf("sbc"); break; case ASSIGN: if (tree->tr2->type!=LONG) { printf("sxt"); goto loop; } default: while ((c = *string++)!='\n' && c!='\0'); break; } goto loop; /* * Mask used in field assignments */ case 'Z': printf("$%o", tree->mask); goto loop; /* * Relational on long values. * Might bug out early. E.g., * (long<0) can be determined with only 1 test. */ case 'X': if (xlongrel(*string++ - '0')) return(reg); goto loop; } putchar(c); goto loop; } /* * This routine just calls sreorder (below) * on the subtrees and then on the tree itself. * It returns non-zero if anything changed. */ reorder(treep, table, reg) struct tnode **treep; struct table *table; { register r, r1; register struct tnode *p; p = *treep; if (opdope[p->op]&LEAF) return(0); r1 = 0; while(sreorder(&p->tr1, table, reg)) r1++; if (opdope[p->op]&BINARY) while(sreorder(&p->tr2, table, reg)) r1++; r = 0; while (sreorder(treep, table, reg)) r++; *treep = optim(*treep); return(r); } /* * Basically this routine carries out two kinds of optimization. * First, it observes that "x + (reg = y)" where actually * the = is any assignment op is better done as "reg=y; x+reg". * In this case rcexpr is called to do the first part and the * tree is modified so the name of the register * replaces the assignment. * Moreover, expressions like "reg = x+y" are best done as * "reg = x; reg =+ y" (so long as "reg" and "y" are not the same!). */ sreorder(treep, table, reg) struct tnode **treep; struct table *table; { register struct tnode *p, *p1; p = *treep; if (opdope[p->op]&LEAF) return(0); if (p->op==PLUS) if (reorder(&p->tr2, table, reg)) *treep = p = optim(p); p1 = p->tr1; if (p->op==STAR || p->op==PLUS) { if (reorder(&p->tr1, table, reg)) *treep = p = optim(p); p1 = p->tr1; } if (p1->op==NAME) switch(p->op) { case ASLSH: case ASRSH: case ASSIGN: if (p1->class != REG||p1->type==CHAR||isfloat(p->tr2)) return(0); if (p->op==ASSIGN) switch (p->tr2->op) { case TIMES: if (!ispow2(p->tr2)) break; p->tr2 = pow2(p->tr2); case PLUS: case MINUS: case AND: case NAND: case OR: case EXOR: case LSHIFT: case RSHIFT: p1 = p->tr2->tr2; if (xdcalc(p1, 16) > 12 || p1->op==NAME &&(p1->nloc==p->tr1->nloc || p1->regno==p->tr1->nloc)) return(0); p1 = p->tr2; p->tr2 = p1->tr1; if (p1->tr1->op!=NAME || p1->tr1->class!=REG || p1->tr1->nloc!=p->tr1->nloc) rcexpr(p, efftab, reg); p->tr2 = p1->tr2; p->op = p1->op + ASPLUS - PLUS; *treep = p; return(1); } goto OK; case ASTIMES: if (!ispow2(p)) return(0); case ASPLUS: case ASMINUS: case ASAND: case ASNAND: case ASOR: case ASXOR: case DECBEF: case INCBEF: OK: if (table==cctab||table==cregtab) reg =+ 020; rcexpr(optim(p), efftab, ~reg); *treep = p1; return(1); } return(0); } /* * Delay handles postfix ++ and -- * It observes that "x + y++" is better * treated as "x + y; y++". * If the operator is ++ or -- itself, * it calls rcexpr to load the operand, letting * the calling instance of rcexpr to do the * ++ using efftab. * Otherwise it uses sdelay to search for inc/dec * among the operands. */ delay(treep, table, reg) struct tnode **treep; { register struct tnode *p, *p1; register r; p = *treep; if (table!=efftab && (p->op==INCAFT||p->op==DECAFT) && p->tr1->op==NAME) { return(1+rcexpr(p->tr1, table, reg)); } p1 = 0; if (opdope[p->op]&BINARY) p1 = sdelay(&p->tr2); if (p1==0) p1 = sdelay(&p->tr1); if (p1) { r = rcexpr(optim(p), table, reg); *treep = p1; return(r+1); } return(0); } sdelay(ap) struct tnode **ap; { register struct tnode *p, *p1; p = *ap; if ((p->op==INCAFT||p->op==DECAFT) && p->tr1->op==NAME) { *ap = ncopy(p->tr1); return(p); } if (p->op==STAR || p->op==PLUS) if (p1=sdelay(&p->tr1))  return(p1); if (p->op==PLUS) return(sdelay(&p->tr2)); return(0); } /* * Copy a tree node for a register variable. * Used by sdelay because if *reg-- is turned * into *reg; reg-- the *reg will in turn * be changed to some offset class, accidentally * modifying the reg--. */ ncopy(ap) struct tname *ap; { register struct tname *p, *q; p = ap; if (p->class!=REG) return(p); q = getblk(sizeof(*p)); q->op = p->op; q->type = p->type; q->class = p->class; q->offset = p->offset; q->nloc = p->nloc; return(q); } /* * If the tree can be immediately loaded into a register, * produce code to do so and return success. */ chkleaf(atree, table, reg) struct tnode *atree; { struct tnode lbuf; register struct tnode *tree; tree = atree; if (tree->op!=STAR && dcalc(tree, nreg-reg) > 12) return(-1); lbuf.op = LOAD; lbuf.type = tree->type; lbuf.degree = tree->degree; lbuf.tr1 = tree; return(rcexpr(&lbuf, table, reg)); } /* * Compile a function argument. * If the stack is currently empty, put it in (sp) * rather than -(sp); this will save a pop. * Return the number of bytes pushed, * for future popping. */ comarg(atree, flagp) int *flagp; { register struct tnode *tree; register retval; tree = atree; if (nstack || isfloat(tree) || tree->type==LONG) { rcexpr(tree, sptab, 0); retval = arlength(tree->type); } else { (*flagp)++; rcexpr(tree, lsptab, 0); retval = 0; } return(retval); } /* * Compile an initializing expression */ doinit(atype, atree) struct tnode *atree; { register struct tnode *tree; register int type; float sfval; double fval; long lval; tree = atree; type = atype; if (type==CHAR) { printf(".byte "); if (tree->type&XTYPE) goto illinit; type = INT; } if (type&XTYPE) type = INT; switch (type) { case INT: if (tree->op==FTOI) { if (tree->tr1->op!=FCON && tree->tr1->op!=SFCON) goto illinit; tree = tree->tr1; tree->value = tree->fvalue; tree->op = CON; } else if (tree->op==LTOI) { if (tree->tr1->op!=LCON) goto illinit; tree = tree->tr1; lval = tree->lvalue; tree->op = CON; tree->value = lval; } if (tree->op == CON) printf("%o\n", tree->value); else if (tree->op==AMPER) { pname(tree->tr1); putchar('\n'); } else goto illinit; return; case DOUBLE: case FLOAT: if (tree->op==ITOF) { if (tree->tr1->op==CON) { fval = tree->tr1->value; } else goto illinit; } else if (tree->op==FCON || tree->op==SFCON) fval = tree->fvalue; else if (tree->op==LTOF) { if (tree->tr1->op!=LCON) goto illinit; fval = tree->tr1->lvalue; } else goto illinit; if (type==FLOAT) { sfval = fval; printf("%o; %o\n", sfval); } else printf("%o; %o; %o; %o\n", fval); return; case LONG: if (tree->op==FTOL) { tree = tree->tr1; if (tree->op==SFCON) tree->op = FCON; if (tree->op!= FCON) goto illinit; lval = tree->fvalue; } else if (tree->op==ITOL) { if (tree->tr1->op != CON) goto illinit; lval = tree->tr1->value; } else if (tree->op==LCON)  lval = tree->lvalue; else goto illinit; printf("%o; %o\n", lval); return; } illinit: error("Illegal initialization"); } movreg(r0, r1, tree) struct tnode *tree; { register char *s; if (r0==r1) return; if (tree->type==LONG) { s = "mov r%d,r%d\nmov r%d,r%d\n"; if (r0 < r1) printf(s, r0+1,r1+1,r0,r1); else printf(s, r0,r1,r0+1,r1+1); return; } printf("mov%c r%d,r%d\n", isfloat(tree), r0, r1); } CON) goto illinit; lval = tree->tr1->value; } else if (tree->op==LCON) nw %b  @& l  @& 7 @~   77~7z v r d @&    , ( $  ww C  _% _@ 555N& 55S 5@ 53Nf %_3"@ 5 5@3Nf %_s@5Nf 5}-   Me@ʋAE@-8ʥ@%$2N&& % &@ 5 E@-@%$  &f % e wRw NB5  @@ 5% C  _\% %  _  d _\N % & & L% _\N %%Q& % 3_ 5 5 % : % Ne  ` Ne  ` Cc % bN `% w%% _\ _%%:3 & ; % 3%L\[   r eA! y% -,% 5Nfe r%C 5 Nfe % %%@_\C%%@_\N `% _\%K% 5BN `% 7 5%%%   .%- &f e %f %&%  %n    " @ww Bu@ 55 %5%6%":%6NJ5& @ eNf %  N Nf %  @_%ZW%_N& 5&  eNf %5w 5&  N Nf %5u-ff L%N @_N 5@ 5% 5 %%: Nf %5@_%(%F %% %%%% &j %2-fZ @5%% %!% N %5Nf %5_@5% 3&: e  35  5$%@ @0&@&W e @AA p@5 5E @_ %+%I% @_D5 ' + N& @5%' 5 f %5 D%b  f %@%b  D5"@e5 ! U555%5%+ %,%I%J5 %%$%%5u 5%uuNf& %5%-_ 55 u- ff L%uQu-M5A  :%65)5 N f AAE@ 5z N  AE@ u@ 5ff L%_ u- u+ - %%t N _ (  %- _ _) + _ @ %$ %  %# & _ @ 5%Nff e_  %   % N N _ % - (% _ @5 %    r e:A! y_   _ @e @_  r epA! y8N _ ww B 5 9 Nfe %   5Nfe %   Nff %  N =wxw tD 5 _n%(Nf&e %  =%$%(Nf&e %  =%_j_P %  _n%PcX Z 4 % %,p  _n%p,N& %e =?(  x  .%-e@@ & & %  r eA! y ww D@t%% %!% Nf& % +  5e  e  Nf&  & %  ww D% %! % p=%$%( e  %(e  ww D  3333wPw L D%$<N& % j555Nffe %ww D  %  & %    & % ww DC%  5_@ 5 _4%4%%_@44%;%_@55t% %#   _@_H%3%05_@%%45%9%_@ 05[%555& Ze 5& Fe D%8%%34 5%: %%5 %55ff e   xT ww u-<@%&u-Nff f & eN f ff& eNff @ &3 ew,<=@A>?DEBC=EDCB'$$&2470^^:f@LX#(#`4444H`>>>>>    d (   0( b R f j L ZZBZZZZZZ".6  jjj@,,@@Arg countMissing temp fileCan't create %s.globl fltused Missing temp file.globl .data mov r%d,-(sp) mov%c r%d,%c(sp) tst%c r%d Illegal operation on structureNo code table for op: %sNo code table for op %d.data L%d:%o;%o;%o;%o .text .data L%d:%o;%o;%o;%o .text Register overflow: simplify expressionr%d*bic r%d,r%d sbc r%d tst r%d sxt r%d adcsbcsxt$%o.byte %o %o; %o %o; %o; %o; %o %o; %o Illegal initializationmov r%d,r%d mov r%d,r%d mov%c r%d,r%d hxhhxhxYI9 )8iHhhx8 yx((((  888hhh        h (99 h (h HHh8(8h8(888888( h Hh( 88h999h88 8_maprel#_notrel#_nreg#_isn#_namsiz#_line _ascbuf _nerror _cctab _efftab _regtab _sptab _lsptab _instab _brancht _opdope _opntab _nstack _nfloat _funcbas _curbase _coremax _eolflg _czero#_cone#_fczero#_xlab1 _xlab2 _xop _xzero _cregtab _main"~maincsv argcargvL2L3b_error _exit _fopen L4BL5l_creat _fout L6tL7~_sbrk _getree L8L9_printf _close L10L11L12_flush L10000L10001L1cret _match"~matchoptnrleftdopetreed1d2p2p1t1t2tableopatreeL14L13L15L16L178L18:_dcalc L19L20L21L22L23L24L25L26L28L27L29 L30L31L10002<_notcomp L32TL33L10003_rcexpr"~rcexpratableregrecurfrmodftreetableatreenargsL35L36L37L38L34\L39L40L41_optim L43L44_doinit"dL45:L46`_movreg"LL47fL48L49_tnode L42L50L51L52L53L54_comarg"L55*_cexpr"`_popstk L10004RL56XL57L58^L59^L60L61zL62L63L64L65L66_pow2 L10007L10006L10010$L10008L10009L67_delay"rL68L69B_reorder"L70BL71ZL72tL73L10011L74_isfloat L10012L75L76L77L10013L10014L78L79 L80L81"L82L83VL84JL85 L86VL87"~cexpr`regctableopdoptstringreg1cflagpraregtreerregp1p2tableatreeL10015L89_cbranch _branch _label L88L90L912L92_oddreg L10016L93_chkleaf"L94.L10017:L95TL96L10018|L97L10019L98 L99 L100> L101:L102 L103 L104WL105 L106 _putchar L108L109 L110 L10020 L111 L112 L113 L114 L115 L116 L117 _pname L118( L119< L120@ _prins L121R L122^ L123` L124j L125b L126z L127f L128z L129 L130 L10021 L131 L132 L133 L134 L135 L136 L137 L138 L139 L140T L10022N L141 _collcon L142 L143| L144 L145 L146 L10023 L147 L148 L10024 L149" L150 L151 L152 L153 L154 L10025 L10026| _xdcalc L155 L156 L157 L158 L159 L160 L10027 L161 L162tL163L164( L165H L166D L107L167L L168` L169d L170r L171j L172 L173 L174L175 L176 _psoct L177 L178 L179 L180 L181L182L183L184L1850L187~L1884L1894L1904L1914L192L186L193>L194>L195>L196>L197>L198L199HL200`L201L202`L203`L204zL10030:L10029L10033XL10031@L10032LL205L206L207_xlongre L208L10036pL10035L10044L10037L10038L10039L10040L10041L10042L10043~reorderregprr1tabletreepL210L209L211_sreorde"L2120L213XL214<L215XL216ZL217t~sreorderegpp1tabletreepL219L218nL220L221L10045L222L223L224jL226PL227L228L229L100460L2306L231L233L234B_ispow2 L232L235ZL236ZL237ZL238ZL239ZL240ZL241ZL242ZL10047L243L10048L10049L244L10051L245L246L247L248L249L250L251L252L253L254L255L10052"L256(L225jL10055L10054bL100596L10056L10057"L10058.~delayrregprp1tabletreepL258L10060L257L259_sdelay" L260L261~sdelay pp1apL10061 L2638_ncopy"pL262lL10062DL264VL265VL266h~ncopyppqapL268L267_getblk ~chkleafreglbuftreetableatreeL270L269 ~comargretvaltreeflagpatreeL10063.L272H_arlengt L273\L271`~doinitdfvaltreelvaltypeatreeatypesfvalL275L276L277@L278L2804L281L282L10064L283L284L285 L286L287(L288$L289(L274HL290,L291,L292NL293HL294LL295L10065ZL296dL297L298L299L300L301L302L303L304L305L306L307L308L309L310L311L312L279@L10067TL313~movregLstreer0r1L314L315L316L317L318L3193fltused (L288$L289(L274HL290,L291,L292NL293HL294LL295L10065ZL296dL297L298L299L300L301L302L303L304L305L306L307L308L309L310L311L312L279@L100# /* * C compiler */ #include "c1.h" max(a, b) { if (a>b) return(a); return(b); } degree(at) struct tnode *at; { register struct tnode *t, *t1; if ((t=at)==0 || t->op==0) return(0); if (t->op == CON) return(-3); if (t->op == AMPER) return(-2); if (t->op==ITOL && (t1 = isconstant(t)) && t1->value>= 0) return(-2); if ((opdope[t->op] & LEAF) != 0) { if (t->type==CHAR || t->type==FLOAT) return(1); return(0); } return(t->degree); } pname(ap, flag) struct tnode *ap; { register i; register struct tnode *p; struct { int intx[2]; }; p = ap; loop: switch(p->op) { case LCON: printf("$%o", flag==2? p->lvalue.intx[1]:p->lvalue.intx[0]); return; case SFCON: case CON: printf("$"); psoct(p->value); return; case FCON: printf("L%d", (p->value>0? p->value: -p->value)); return; case NAME: i = p->offset; if (flag==2) i =+ 2; if (i) { psoct(i); if (p->class!=OFFS) putchar('+'); if (p->class==REG) regerr(); } switch(p->class) { case SOFFS: case XOFFS: pbase(p); case OFFS: printf("(r%d)", p->regno); return; case EXTERN: case STATIC: pbase(p); return; case REG: printf("r%d", p->nloc); return; } error("Compiler error: pname"); return; case AMPER: putchar('$'); p = p->tr1; if (p->op==NAME && p->class==REG) regerr(); goto loop; case AUTOI: printf("(r%d)%c", p->nloc, flag==1?0:'+'); return; case AUTOD: printf("%c(r%d)", flag==1?0:'-', p->nloc); return; case STAR: p = p->tr1;  putchar('*'); goto loop; } error("pname called illegally"); } regerr() { error("Illegal use of register"); } pbase(ap) struct tnode *ap; { register struct tnode *p; p = ap; if (p->class==SOFFS || p->class==STATIC) printf("L%d", p->nloc); else printf("_%.8s", &(p->nloc)); } xdcalc(ap, nrleft) struct tnode *ap; { register struct tnode *p; register d; p = ap; d = dcalc(p, nrleft); if (d<20 && p->type==CHAR) { if (nrleft>=1) d = 20; else d = 24; } return(d); } dcalc(ap, nrleft) struct tnode *ap; { register struct tnode *p, *p1; if ((p=ap)==0) return(0); switch (p->op) { case NAME: if (p->class==REG) return(9); case AMPER: case FCON: case LCON: case AUTOI: case AUTOD: return(12); case CON: case SFCON: if (p->value==0) return(4); if (p->value==1) return(5); if (p->value > 0) return(8); return(12); case STAR: p1 = p->tr1; if (p1->op==NAME||p1->op==CON||p1->op==AUTOI||p1->op==AUTOD) if (p->type!=LONG) return(12); } if (p->type==LONG) nrleft--; return(p->degree <= nrleft? 20: 24); } notcompat(ap, ast, op) struct tnode *ap; { register at, st; register struct tnode *p; p = ap; at = p->type; st = ast; if (st==0) /* word, byte */ return(at>CHAR && atINT && atop==NAME && p->class==REG && op==ASSIGN && st==CHAR) return(0); return(st != at); } prins(op, c, itable) struct instab *itable; { register struct instab *insp; register char *ip; for (insp=itable; insp->op != 0; insp++) { if (insp->op == op) { ip = c? insp->str2: insp->str1; if (ip==0) break; printf("%s", ip); return; } } error("No match' for op %d", op); } collcon(ap) struct tnode *ap; { register op; register struct tnode *p; p = ap; if (p->op==STAR) { if (p->type==LONG+PTR) /* avoid *x(r); *x+2(r) */ return(0); p = p->tr1; } if (p->op==PLUS) { op = p->tr2->op; if (op==CON || op==AMPER) return(1); } return(0); } isfloat(at) struct tnode *at; { register struct tnode *t; t = at; if ((opdope[t->op]&RELAT)!=0) t = t->tr1; if (t->type==FLOAT || t->type==DOUBLE) { nfloat = 1; return('f'); } return(0); } oddreg(t, areg) struct tnode *t; { register reg; reg = areg; if (!isfloat(t)) switch(t->op) { case LLSHIFT: case ASLSHL: return((reg+1)&~01); case DIVIDE: case MOD: case ASDIV: case ASMOD: case PTOI: reg++; case TIMES: case ASTIMES: return(reg|1); } return(reg); } arlength(t) { if (t>=PTR) return(2); switch(t) { case INT: case CHAR: return(2); case LONG: return(4); case FLOAT: case DOUBLE: return(8); } return(1024); } /* * Strings for switch code. */ char dirsw[] {"\ cmp r0,$%o\n\ jhi L%d\n\ asl r0\n\ jmp *L%d(r0)\n\ .data\n\ L%d:\ " }; char simpsw[] {"\ mov $L%d,r1\n\ mov r0,L%d\n\ L%d:cmp r0,(r1)+\n\ jne L%d\n\ jmp *L%d-L%d(r1)\n\ .data\n\ L%d:\ "}; char hashsw[] {"\ mov r0,r1\n\ clr r0\n\ div $%o,r0\n\ asl r1\n\ add $L%d,r1\n\ mov r0,*(r1)+\n\ mov (r1)+,r1\n\ L%d:cmp r0,-(r1)\n\ jne L%d\n\ jmp *L%d-L%d(r1)\n\ .data\n\ L%d:\ "}; pswitch(afp, alp, deflab) struct swtab *afp, *alp; { int tlab, ncase, i, j, tabs, worst, best, range; register struct swtab *swp, *fp, *lp; int *poctab; fp = afp; lp = alp; if (fp==lp) { printf("jbr L%d\n", deflab); return; } tlab = isn++; if (sort(fp, lp)) return; ncase = lp-fp; lp--; range = lp->swval - fp->swval; /* direct switch */ if (range>0 && range <= 3*ncase) { if (fp->swval) printf("sub $%o,r0\n", fp->swval); printf(dirsw, range, deflab, isn, isn); isn++; for (i=fp->swval; i<=lp->swval; i++) { if (i==fp->swval) { printf("L%d\n", fp->swlab); fp++; } else printf("L%d\n", deflab); } goto esw; } /* simple switch */ if (ncase<8) { i = isn++; j = isn++; printf(simpsw, i, j, isn, isn, j, i, i); isn++; for (; fp<=lp; fp++) printf("%o\n", fp->swval);  printf("L%d:..\n", j); for (fp = afp; fp<=lp; fp++) printf("L%d\n", fp->swlab); printf("L%d\n", deflab); goto esw; } /* hash switch */ best = 077777; poctab = getblk(((ncase+2)/2) * sizeof(*poctab)); for (i=ncase/4; i<=ncase/2; i++) { for (j=0; jswval, i)]++; worst = 0; for (j=0; jworst) worst = poctab[j]; if (i*worst < best) { tabs = i; best = i*worst; } } i = isn++; printf(hashsw, tabs, isn, i, i, isn+tabs+1, isn+1, isn); isn++; for (i=0; i<=tabs; i++) printf("L%d\n", isn+i); for (i=0; iswval, tabs) == i) printf("%o\n", ldiv(0, swp->swval, tabs)); } printf("L%d:", isn++); for (i=0; iswval, tabs) == i) printf("L%d\n", swp->swlab); } esw: printf(".text\n"); } sort(afp, alp) struct swtab *afp, *alp; { register struct swtab *cp, *fp, *lp; int intch, t; fp = afp; lp = alp; while (fp < --lp) { intch = 0; for (cp=fp; cpswval == cp[1].swval) { error("Duplicate case (%d)", cp->swval); return(1); } if (cp->swval > cp[1].swval) { intch++; t = cp->swval; cp->swval = cp[1].swval; cp[1].swval = t; t = cp->swlab; cp->swlab = cp[1].swlab; cp[1].swlab = t; } } if (intch==0) break; } return(0); }  ispow2(atree) { register int d; register struct tnode *tree; tree = atree; if (!isfloat(tree) && tree->tr2->op==CON) { d = tree->tr2->value; if (d>1 && (d&(d-1))==0) return(d); } return(0); } pow2(atree) struct tnode *atree; { register int d, i; register struct tnode *tree; tree = atree; if (d = ispow2(tree)) { for (i=0; (d=>>1)!=0; i++); tree->tr2->value = i; d = tree->op; tree->op = d==TIMES? LSHIFT: ASLSH; tree = optim(tree); } return(tree); } cbranch(atree, albl, cond, areg) struct tnode *atree; { int l1, op; register lbl, reg; register struct tnode *tree; lbl = albl; reg = areg; if ((tree=atree)==0) return; switch(tree->op) { case LOGAND: if (cond) { cbranch(tree->tr1, l1=isn++, 0, reg); cbranch(tree->tr2, lbl, 1, reg); label(l1); } else { cbranch(tree->tr1, lbl, 0, reg); cbranch(tree->tr2, lbl, 0, reg); } return; case LOGOR: if (cond) { cbranch(tree->tr1, lbl, 1, reg); cbranch(tree->tr2, lbl, 1, reg); } else { cbranch(tree->tr1, l1=isn++, 1, reg); cbranch(tree->tr2, lbl, 0, reg); label(l1); } return; case EXCLA: cbranch(tree->tr1, lbl, !cond, reg); return; case SEQNC: rcexpr(tree->tr1, efftab, reg); tree = tree->tr2; break; } op = tree->op; if (tree->type==LONG || opdope[op]&RELAT&&tree->tr1->type==LONG) { longrel(tree, lbl, cond, reg); return; } rcexpr(tree, cctab, reg); op = tree->op; if ((opdope[op]&RELAT)==0) op = NEQUAL; else { l1 = tree->tr2->op; if ((l1==CON || l1==SFCON) && tree->tr2->value==0) op =+ 200; /* special for ptr tests */ else op = maprel[op-EQUAL]; } if (isfloat(tree)) printf("cfcc\n"); branch(lbl, op, !cond); } branch(lbl, aop, c) { register op; if(op=aop) prins(op, c, branchtab); else printf("jbr"); printf("\tL%d\n", lbl); } longrel(atree, lbl, cond, reg) struct tnode *atree; { int xl1, xl2, xo, xz; register int op, isrel; register struct tnode *tree; reorder(&atree, cctab, reg); tree = atree; isrel = 0; if (opdope[tree->op]&RELAT) { isrel++; op = tree->op; } else op = NEQUAL; if (!cond) op = notrel[op-EQUAL]; xl1 = xlab1; xl2 = xlab2; xo = xop; xlab1 = lbl; xlab2 = 0; xop = op; xz = xzero; xzero = !isrel || tree->tr2->op==ITOL && tree->tr2->tr1->op==CON && tree->tr2->tr1->value==0; if (tree->op==NAND) { tree->op = TAND; tree->tr2 = optim(tnode(COMPL, LONG, tree->tr2)); } doitover: if (cexpr(tree, cctab, reg) < 0) { if (tree->op==TAND) { tree->op = NAND; tree->tr2 = optim(tnode(COMPL, LONG, tree->tr2)); goto doitover; } if (isrel) { tree->op = MINUS; tree->type = LONG; tree = optim(tree); } printf("ashc $0,r%d\n", rcexpr(tree, regtab, reg)); branch(xlab1, op, 0); } xlab1 = xl1; xlab2 = xl2; xop = xo; xzero = xz; } /* * Tables for finding out how best to do long comparisons. * First dimen is whether or not the comparison is with 0. * Second is which test: e.g. a>b-> * cmp a,b * bgt YES (first) * blt NO (second) * cmp a+2,b+2 * bhi YES (third) * NO: ... * Note some tests may not be needed. */ char lrtab[2][3][6] { 0, NEQUAL, LESS, LESS, GREAT, GREAT, NEQUAL, 0, GREAT, GREAT, LESS, LESS, EQUAL, NEQUAL, LESSEQP,LESSP, GREATQP,GREATP, 0, NEQUAL, LESS, LESS, GREATEQ,GREAT, NEQUAL, 0, GREAT, 0, 0, LESS, EQUAL, NEQUAL, EQUAL, 0, 0, NEQUAL, }; xlongrel(f) { register int op, bno; register char *tp; op = xop; if (f==0) { if (bno = lrtab[xzero][0][op-EQUAL]) branch(xlab1, bno, 0); if (bno = lrtab[xzero][1][op-EQUAL]) { xlab2 = isn++; branch(xlab2, bno, 0); } if (lrtab[xzero][2][op-EQUAL]==0) return(1); } else { branch(xlab1, lrtab[xzero][2][op-EQUAL], 0); if (xlab2) label(xlab2); } return(0); } label(l) { printf("L%d:", l); } popstk(a) { switch(a) { case 0: return; case 2: printf("tst (sp)+\n"); return; case 4: printf("cmp (sp)+,(sp)+\n"); return; } printf("add $%o,sp\n", a); } error(s, p1, p2, p3, p4, p5, p6) { register f; extern fout; nerror++; flush(); f = fout; fout = 1; printf("%d: ", line); printf(s, p1, p2, p3, p4, p5, p6); putchar('\n'); flush(); fout = f; } psoct(an) { register int n, sign; sign = 0; if ((n = an) < 0) { n = -n; sign = '-'; } printf("%c%o", sign, n); } /* * Read in an intermediate file. */ getree() { LTYPE itol(); struct tnode *expstack[20]; register struct tnode **sp; register t, op; static char s[9]; struct swtab *swp; double atof(); char numbuf[64]; struct tname *np; struct xtname *xnp; struct ftconst *fp; struct lconst *lp; int lbl, cond; curbase = funcbase; sp = expstack; for (;;) { if (sp >= &expstack[20]) error("Stack botch"); op = getw(ascbuf); if ((op&0177400) != 0177000) { error("Intermediate file error"); exit(1); } lbl = 0; switch(op =& 0377) { case SINIT: printf("%o\n", getw(ascbuf)); break; case EOF: return; case BDATA: if (getw(ascbuf) == 1) { printf(".byte "); for (;;) { printf("%o", getw(ascbuf)); if (getw(ascbuf) != 1) break; printf(","); } printf("\n"); }  break; case PROG: printf(".text\n"); break; case DATA: printf(".data\n"); break; case BSS: printf(".bss\n"); break; case SYMDEF: printf(".globl _%s\n", outname(s)); break; case RETRN: printf("jmp cret\n"); break; case CSPACE: t = outname(s); printf(".comm _%s,%o\n", t, getw(ascbuf)); break; case SSPACE: printf(".=.+%o\n", getw(ascbuf)); break; case EVEN: printf(".even\n"); break; case SAVE: printf("jsr r5,csv\n"); break; case SETSTK: t = getw(ascbuf)-6; if (t==2) printf("tst -(sp)\n"); else if (t != 0) printf("sub $%o,sp\n", t); break; case PROFIL: t = getw(ascbuf); printf("mov $L%d,r0\njsr pc,mcount\n", t); printf(".bss\nL%d:.=.+2\n.text\n", t); break; case SNAME: t = outname(s); printf("~%s=L%d\n", t, getw(ascbuf)); break; case ANAME: t = outname(s); printf("~%s=%o\n", t, getw(ascbuf)); break; case RNAME: t = outname(s); printf("~%s=r%d\n", t, getw(ascbuf)); break; case SWIT: t = getw(ascbuf); line = getw(ascbuf); curbase = funcbase; while(swp=getblk(sizeof(*swp)), swp->swlab = getw(ascbuf)) swp->swval = getw(ascbuf); pswitch(funcbase, swp, t); break; case CBRANCH: lbl = getw(ascbuf); cond = getw(ascbuf); case EXPR: line = getw(ascbuf); if (sp != &expstack[1]) { error("Expression input botch"); exit(1); } nstack = 0; *sp = optim(*--sp); if (lbl) cbranch(*sp, lbl, cond, 0); else rcexpr(*sp, efftab, 0); curbase = funcbase; break; case NAME: t = getw(ascbuf); if (t==EXTERN) { np = getblk(sizeof(*xnp)); np->type = getw(ascbuf); outname(np->name); } else { np = getblk(sizeof(*np)); np->type = getw(ascbuf); np->nloc = getw(ascbuf); } np->op = NAME; np->class = t; np->regno = 0; np->offset = 0; *sp++ = np; break; case CON: getw(ascbuf); /* ignore type, assume int */ *sp++ = tconst(getw(ascbuf)); break; case LCON: getw(ascbuf); /* ignore type, assume long */ t = getw(ascbuf); op = getw(ascbuf); if (t==0 && op>=0 || t == -1 && op<0) { *sp++ = tnode(ITOL, LONG, tconst(op)); break; } lp = getblk(sizeof(*lp)); lp->op = LCON; lp->type = LONG; lp->lvalue = itol(t, op); *sp++ = lp; break; case FCON: t = getw(ascbuf); outname(numbuf); fp = getblk(sizeof(*fp)); fp->op = FCON; fp->type = t; fp->value = isn++; fp->fvalue = atof(numbuf); *sp++ = fp; break; case FSEL: *sp = tnode(FSEL, getw(ascbuf), *--sp, NULL); t = getw(ascbuf); (*sp++)->tr2 = tnode(COMMA, INT, tconst(getw(ascbuf)), tconst(t)); break; case NULLOP: *sp++ = tnode(0, 0, NULL, NULL); break; case LABEL: label(getw(ascbuf)); break; case NLABEL: t = outname(s); printf("_%s:\n", t, t); break; case RLABEL: t = outname(s); printf("_%s:\n~~%s:\n", t, t, t); break; case BRANCH: branch(getw(ascbuf), 0); break; case SETREG: nreg = getw(ascbuf)-1; break; default: if (opdope[op]&BINARY) { if (sp < &expstack[1]) { error("Binary expression botch"); exit(1); } t = *--sp; *sp++ = tnode(op, getw(ascbuf), *--sp, t); } else { sp[-1] = tnode(op, getw(ascbuf), sp[-1]); } break; } } } outname(s) { register char *p, c; register n; p = s; n = 0; while (c = getc(ascbuf)) { *p++ = c; n++; } do { *p++ = 0; } while (n++ < 8); return(s); } branch(getw(ascbuf), 0); break; case SETREG: nreg = getw(ascbuf)-1; break; default: if (opdope[op]&BINARY) { if (sp < &expstack[1]) { error("Binary expression botch"); exit(1); }  <w u-@@ww D   0%*%#$%:    5 %% wlw hC_% _   _    _ %e  +    ` \ T   x rF$ % r_% + %%%& - %* _  x0 rww  rww D  e ww DN&  % % %wfw bD  P6 G D >%7 1 .% %%%%   xR% t-ww BC %% :%  % -55EU%%%  %P% ! ww D L-   eN r ww C%$% %( %%# ww |D 5%%Rf wDw @DN  @  E U  r etA! yww %@     xww CB N2 _   _@ r55 AAWpA-: ; "ff e ,, G eNL _%I  Nffff e ~ Q eNU C ] eNb _Ae r  5A r5A r@-N5 u- @ @m  N&& % @m e5 5 u-@ @mH-@ @m5 AupA- uAupu N HD@ :Nm ff(f2 e 5 u- Nmg 5 u-+ l  N&& %@-N&& %t e  x 5 u-!N}  N&& %@- e  w"w CB 05  '4-  r 4- 54t5 te  ww C  % % 1 wfw bB ^   %*.L  ww DC B _ _ & 5&  e& eN & & e& & e_ & e& eV5& L e& & eN _  & & e_  % 7  y% @ 5% f& $ eD %@ 5=%%  e@5    f& %ww D f& % N ww N fe %B  5 = w7 ~7zv %: %  7B%7Q& % 2N  % 4%Q7& % 2 ) N  %  & %wwwwww | 0rWpaC ^ %TWpaC DB > 6 %,Wpa@ WpaAf %   ww N ww @     xN ww ~xt Nff f fff e  :76w2w . D  - %ww vDe@e! r E% r 5 E_  __ %  %  %( * _, _3 _: _" @  _L _"  V %_ d _l _s _ e%   _   _"   %_"   %_"   %_  7 5 =  A1f P%_ 5 5 7d@e! r 7 F   ff& e & %_ %  5 A1Ne  5 A1 A1@@0@0 T_   _     %  : %_ 5@ f&@T_ Ne  5@@ Ne A1T_ & x & e    L & D &&  e1e_ & & & e_  o"  %b"  eS  & H 7@ 5@e!  r & l & e N & %4  r eA! yP_ ww D  Ԑ  %@wLLTvvvvv:44********z$%.$-&&22FF,cmp r0,$%o jhi L%d asl r0 jmp *L%d(r0) .data L%d:mov $L%d,r1 mov r0,L%d L%d:cmp r0,(r1)+ jne L%d jmp *L%d-L%d(r1) .data L%d:mov r0,r1 clr r0 div $%o,r0 asl r1 add $L%d,r1 mov r0,*(r1)+ mov (r1)+,r1 L%d:cmp r0,-(r1) jne L%d jmp *L%d-L%d(r1) .data L%d:"56a  p ( =??AA=AA??<=BCDE=??@A=A?<=<=<`>`H",6@JRX    `j`|L`n`:@X`xR`&`P``($%o$L%d(r%d)r%dCompiler error: pname(r%d)%c%c(r%d)pname called illegallyIllegal use of registerL%d_%.8s%sNo match' for op %djbr L%d sub $%o,r0 L%d L%d %o L%d:.. L%d L%d L%d L%d:.. %o L%d:L%d L%d .text Duplicate case (%d)cfcc jbr L%d ashc $0,r%d L%d:tst (sp)+ cmp (sp)+,(sp)+ add $%o,sp %d: %c%oStack botchIntermediate file error%o .byte %o, .text .data .bss .globl _%s jmp cret .comm _%s,%o .=.+%o .even jsr r5,csv tst -(sp) sub $%o,sp mov $L%d,r0 jsr pc,mcount .bss L%d:.=.+2 .text ~%s=L%d ~%s=%o ~%s=r%d Expression input botch_%s: _%s: ~~%s: Binary expression botch Y Y Y Y Y Y Y Y Y Y )Y Y Y 999999999999h9999999999h99hY Y Y Y 9999hhY Y hhhY 99Y Y Y yiyyYiyY Y 9IhH!x!hH!hH!hH!hH!hH!hH!hH!hH!hH!hH!hH!hH!hH!Y9IhH!hH!9hH!hH!hH!Yx!h9IhH!hH!hH!hH!hH!hH!X%hH!hH!hH!X%h%hH!99%hI!hhH!X%hI!Y%hhhH!hI!hH!)x!hI!hhI!hY h'Y_maprel _notrel _nreg _isn _namsiz _line _ascbuf _nerror _cctab _efftab _regtab _sptab _lsptab _instab _brancht _opdope _opntab _nstack _nfloat _funcbas _curbase _coremax _eolflg _czero _cone _fczero _xlab1 _xlab2 _xop _xzero _max"~maxcsv abL2L1cret _degree"~degreett1atL10000,L40L3L5<L6HL7d_isconst L8L10001L9_pname"~pnameiflagpapL11L13L14L10002L10003L15_printf L10 L16L17L18_psoct"L19L10004L10005L20L21L22L23.L24"_putchar L25._regerr"L27fL284L294_pbase" L30:L31L32LL33LL34TL35L26vL10007L36_error"rL37L38L39L10008L10009L40L41L10010L10011L42L43L12L100130L44~regerrL46L45~pbase papL100148L48HL49L50XL51L47X_xdcalc"\~xdcalc\nrleftdpap_dcalc"L53L54L55L52~dcalcnrleftpp1apL57L56JL59L60L61L62L63L64L65L66L67L68L69L70L71L72L10015 L73L74L58*L10017RL756L10018DL10019H_notcomp"N~notcompNastpapatopstL77xL10021nL10020rL10022vL76L78L10024L10023L10025L79L80L81L82L10026L10027_prins"~prinsitablecinspipopL84L85,L87&L10028L10029L88L83:L86&L89_collcon">~collcon>papopL91\L92XL90|L93xL10030rL94x_isfloat"~isfloattatL96L10031L97L95_oddreg"~oddregregaregtL99L101L102L103L98 L104L105L106L107L108L109L110L100L10034tL10033L10037L10035zL10036_arlengt"~arlengttL112 L111LL114:L115&L116&L117,L1182L1192L113FL10039_dirsw#_simpsw#_hashsw#2_pswitch"P~pswitchPdeflabafpalppoctabswpijtlabtabsbestfplpncaserangeworstL124vL1252L123_sort"L126:L127L128;L129L1306L132"L133GL1340L135LL1310L136L137L138L139L141QL140L142UL143L144L146]L145L147b_getblk L148L149L151L1520L153*L1542L155T_lrem L156NL157\L158L160L159L161L150L162L163L165gL164 L166L167rL169lL1700L171lL173f_ldiv L174tL172fL168lL175xL176L177L179}L180L181L183L184L182L178L185~sortafpalptcpfplpintchL187L188V L189L190N L192 L193L186Z L194H L191H _ispow2"^ ~ispow2^ dtreeatreeL196 L197 L195 _pow2" ~pow2 ditreeatreeL199 L200 L201 L202 L10040 L10041 _optim L198 _cbranch" ~cbranch lblregalblareg condtreel1opatreeL203 L205 L206 L207H _label"L208l L209p L210 L211 L212 L10042 L10043 L213 _rcexpr L204( L10045L10046L10047 L10048N L214b _longrel"$ L215 L216 L10049 L217 L218 L219 L220L10050 L10051 _branch" ~branch lblaopcopL222 L223 L224L225L221 ~longrel$ lblreg condtreeopatreexoxzisrelxl1xl2_reorder L227X L228\ L229f L10052 L10053 L10054 L230 _tnode L231 _cexpr L232` L233 L2346 L235L226x _lrtab#_xlongre"| ~xlongre| bnofoptpL237 L238 L239 L240 L236L241L242~labellL244L243._popstk"2~popstk2aL247TL248<L245nL249>L250L251HL252L246`L10056L253~errorrfsp1p2p3 p4 p5p6_flush _fout L255L254~psoctnsignanL257L258L256_getree"~getreeL260"lblswpnumbufxnps"tcondfplpnpopspexpstackL261 L263L264_getw L265DL266_exit L268L269RL270L267L271jL259L272nL273L274L275L277%L276L278(L279*L280L281,L282L2833L284L285:L286_outname"L287@L288L289LL290L291VL292(L293dL294@L295lL296LL297sL298XL299vL300L301L302L303L304L305L306L307L308L309L310L311L312L313L3148L315dL316xL317L318L319L320L321L322L3230L324\L325_tconst L326L10058L10057L327_itol L328&_atof L329|L330L331L332L333L334L335L336:L337PL338`L339L340L341 L342L10061L10060L10071XL10062L10063L10064L10065"L10066,L100676L10068@L10069JL10070RL262~outnamecnpsL344_getc L345L348L346L347L343fltused l L328&_atof L329|L330L331L332L333L334L335L336:L337PL338`L339L340L341 L342L10061L10060L10071XL10062L10063L10064L10065"L10066,L100676L10068@L10069JL10070RL262~outname# /* * C compiler part 2 -- expression optimizer * */ #include "c1.h" optim(atree) struct tnode *atree; { struct { int intx[4]; }; register op, dope; int d1, d2; struct tnode *t; register struct tnode *tree; if ((tree=atree)==0) return(0); if ((op = tree->op)==0) return(tree); if (op==NAME && tree->class==AUTO) { tree->class = OFFS; tree->regno = 5; tree->offset = tree->nloc; } dope = opdope[op]; if ((dope&LEAF) != 0) { if (op==FCON && tree->fvalue.intx[1]==0 && tree->fvalue.intx[2]==0 && tree->fvalue.intx[3]==0) { tree->op = SFCON; tree->value = tree->fvalue.intx[0]; } return(tree); } if ((dope&BINARY) == 0) return(unoptim(tree)); /* is known to be binary */ if (tree->type==CHAR) tree->type = INT; switch(op) { /* * PDP-11 special: * generate new =&~ operator out of =& * by complementing the RHS. */ case ASAND: tree->op = ASNAND; tree->tr2 = tnode(COMPL, tree->tr2->type, tree->tr2); break; /* * On the PDP-11, int->ptr via multiplication * Longs are just truncated. */ case LTOP: tree->op = ITOP; tree->tr1 = unoptim(tnode(LTOI,INT,tree->tr1)); case ITOP: tree->op = TIMES; break; case MINUS: if (t = isconstant(tree->tr2)) { tree->op = PLUS; if (t->type==DOUBLE) /* PDP-11 FP representation */ t->value =^ 0100000; else t->value = -t->value; } break; } op = tree->op; dope = opdope[op]; if (dope&LVALUE && tree->tr1->op==FSEL) return(lvfield(tree)); if ((dope&COMMUTE)!=0) { d1 = tree->type;  tree = acommute(tree); if (tree->op == op) tree->type = d1; /* * PDP-11 special: * replace a&b by a NAND ~ b. * This will be undone when in * truth-value context. */ if (tree->op!=AND) return(tree); tree->op = NAND; tree->tr2 = tnode(COMPL, tree->tr2->type, tree->tr2); } again: tree->tr1 = optim(tree->tr1); tree->tr2 = optim(tree->tr2); if ((dope&RELAT) != 0) { if ((d1=degree(tree->tr1)) < (d2=degree(tree->tr2)) || d1==d2 && tree->tr1->op==NAME && tree->tr2->op!=NAME) { t = tree->tr1; tree->tr1 = tree->tr2; tree->tr2 = t; tree->op = maprel[op-EQUAL]; } if (tree->tr1->type==CHAR && tree->tr2->op==CON && (dcalc(tree->tr1) <= 12 || tree->tr1->op==STAR) && tree->tr2->value <= 127 && tree->tr2->value >= 0) tree->tr2->type = CHAR; } d1 = max(degree(tree->tr1), islong(tree->type)); d2 = max(degree(tree->tr2), 0); switch (op) { /* * In assignment to fields, treat all-zero and all-1 specially. */ case FSELA: if (tree->tr2->op==CON && tree->tr2->value==0) { tree->op = ASAND; tree->tr2->value = ~tree->mask; return(optim(tree)); } if (tree->tr2->op==CON && tree->mask==tree->tr2->value) { tree->op = ASOR; return(optim(tree)); } case LTIMES: case LDIV: case LMOD: case LASTIMES: case LASDIV: case LASMOD: tree->degree = 10; break; case NAND: if (isconstant(tree->tr2) && tree->tr2->value==0) return(tree->tr1); goto def; case CALL: tree->degree = 10; break; case QUEST: case COLON: tree->degree = max(d1, d2); break; case DIVIDE: case ASDIV: case ASTIMES: case PTOI: if (tree->tr2->op==CON && tree->tr2->value==1) return(tree->tr1); case MOD: case ASMOD: d1 =+ 2; d2 =+ 2; if (tree->type==LONG) return(hardlongs(tree)); goto constant; case LSHIFT: case RSHIFT: case ASRSH: case ASLSH: if (tree->tr2->op==CON && tree->tr2->value==0) return(tree->tr1); /* * PDP-11 special: turn right shifts into negative * left shifts */ if (tree->type == LONG) { d1++; d2++; } if (op==LSHIFT||op==ASLSH) goto constant; if (tree->tr2->op==CON && tree->tr2->value==1) goto constant; op =+ (LSHIFT-RSHIFT); tree->op = op; tree->tr2 = tnode(NEG, tree->type, tree->tr2); goto again; constant: if (tree->tr1->op==CON && tree->tr2->op==CON) { const(op, &tree->tr1->value, tree->tr2->value); return(tree->tr1); } def: default: tree->degree = d1==d2? d1+islong(tree->type): max(d1, d2); break; } return(tree); } unoptim(atree) struct tnode *atree; { struct { int intx[4]; }; register struct tnode *subtre, *tree; register int *p; double static fv; struct { int integer; }; struct ftconst *fp; if ((tree=atree)==0) return(0); again: subtre = tree->tr1 = optim(tree->tr1); switch (tree->op) { case LTOI: p = tree->tr1; if (p->op == NAME) { p->offset =+ 2; p->type = INT; return(p); } if (p->op == STAR) { p->type = INT; p->tr1->type = INT+PTR; p->tr1 = tnode(PLUS, INT, p->tr1, tconst(2)); return(optim(p)); } if (p->op == ITOL) return(p->tr1); break; case FSEL: tree->op = AND; tree->tr1 = tree->tr2->tr1; tree->tr2->tr1 = subtre; tree->tr2->op = RSHIFT; tree->tr1->value = (1 << tree->tr1->value) - 1; return(optim(tree)); case FSELR: tree->op = LSHIFT; tree->type = INT; tree->tr1 = tree->tr2; tree->tr1->op = AND; tree->tr2 = tree->tr2->tr2; tree->tr1->tr2 = subtre; tree->tr1->tr1->value = (1 << tree->tr1->tr1->value) -1; return(optim(tree)); case AMPER: if (subtre->op==STAR) return(subtre->tr1); if (subtre->op==NAME && subtre->class == OFFS) { p = tnode(PLUS, tree->type, subtre, tree); subtre->type = tree->type; tree->op = CON; tree->type = INT; tree->degree = 0; tree->value = subtre->offset; subtre->class = REG; subtre->nloc = subtre->regno; subtre->offset = 0; return(optim(p)); } break; case STAR: if (subtre->op==AMPER) return(subtre->tr1); if (subtre->op==NAME && subtre->class==REG) { subtre->type = tree->type; subtre->class = OFFS; subtre->regno = subtre->nloc; return(subtre); } p = subtre->tr1; if ((subtre->op==INCAFT||subtre->op==DECBEF)&&tree->type!=LONG && p->op==NAME && p->class==REG && p->type==subtre->type) { p->type = tree->type; p->op = subtre->op==INCAFT? AUTOI: AUTOD; return(p); } if (subtre->op==PLUS && p->op==NAME && p->class==REG) { if (subtre->tr2->op==CON) { p->offset =+ subtre->tr2->value; p->class = OFFS; p->type = tree->type; p->regno = p->nloc; return(p); } if (subtre->tr2->op==AMPER) { subtre = subtre->tr2->tr1; subtre->class =+ XOFFS-EXTERN; subtre->regno = p->nloc; subtre->type = tree->type; return(subtre); } } break; case EXCLA: if ((opdope[subtre->op]&RELAT)==0) break; tree = subtre; tree->op = notrel[tree->op-EQUAL]; break; case NEG: case COMPL: if (tree->type==CHAR) tree->type = INT; if (tree->op == subtre->op) return(subtre->tr1); if (subtre->op==ITOL) { subtre->op = tree->op; subtre->type = INT; tree->op = ITOL; goto again; } if (tree->op!=NEG) break; /* * PDP-11 FP negation */ if (subtre->op==SFCON) { subtre->value =^ 0100000; subtre->fvalue.intx[0] =^ 0100000; return(subtre); } if (subtre->op==FCON) { subtre->fvalue.intx[0] =^ 0100000; return(subtre); } if (subtre->op == LCON) { subtre->lvalue = -subtre->lvalue; return(subtre); } } if (subtre->op == CON) switch(tree->op) { case NEG: subtre->value = -subtre->value; return(subtre); case COMPL: subtre->value = ~subtre->value; return(subtre); case ITOF: fv = subtre->value; p = &fv; p++; if (*p++==0 && *p++==0 && *p++==0) { tree = getblk(sizeof(*fp)); tree->op = SFCON; tree->type = DOUBLE; tree->value = fv.integer; tree->fvalue = fv; return(tree); } break; } tree->degree = max(islong(tree->type), degree(subtre)); return(tree); } /* * Deal with assignments to partial-word fields. * The game is that select(x) =+ y turns into * select(x =+ select(y)) where the shifts and masks * are chosen properly. The outer select * is discarded where the value doesn't matter. * Sadly, overflow is undetected on =+ and the like. * Pure assignment is handled specially. */ lvfield(at) struct tnode *at; { register struct tnode *t, *t1; register struct fasgn *t2; t = at; switch (t->op) { case ASSIGN: t2 = getblk(sizeof(*t2)); t2->op = FSELA; t2->type = INT; t1 = t->tr1->tr2; t2->mask = ((1<tr1->value)-1)<tr2->value; t2->tr1 = t->tr1; t2->tr2 = t->tr2; t = t2; case ASNAND: case ASPLUS: case ASMINUS: case ASOR: case ASXOR: case INCBEF: case INCAFT: case DECBEF: case DECAFT: t1 = t->tr1; t1->op = FSELR; t->tr1 = t1->tr1; t1->tr1 = t->tr2; t->tr2 = t1; t1 = t1->tr2; t1 = tnode(COMMA, INT, tconst(t1->tr1->value), tconst(t1->tr2->value)); return(optim(tnode(FSELT, INT, t, t1))); } error("Unimplemented field operator"); return(t); } struct acl { int nextl; int nextn; struct tnode *nlist[20]; struct tnode *llist[21]; }; acommute(atree) { struct acl acl; int d, i, op, flt, d1; register struct tnode *t1, **t2, *tree; struct tnode *t; acl.nextl = 0; acl.nextn = 0; tree = atree; op = tree->op; flt = isfloat(tree); insert(op, tree, &acl); acl.nextl--; t2 = &acl.llist[acl.nextl]; if (!flt) { /* put constants together */ for (i=acl.nextl;i>0&&t2[0]->op==CON&&t2[-1]->op==CON;i--) { acl.nextl--; t2--; const(op, &t2[0]->value, t2[1]->value); } } if (op==PLUS || op==OR) { /* toss out "+0" */ if (acl.nextl>0 && (t1 = isconstant(*t2)) && t1->value==0) { acl.nextl--; t2--; } if (acl.nextl <= 0) return(*t2); /* subsume constant in "&x+c" */ if (op==PLUS && t2[0]->op==CON && t2[-1]->op==AMPER) { t2--; t2[0]->tr1->offset =+ t2[1]->value; acl.nextl--; } } else if (op==TIMES || op==AND) { t1 = acl.llist[acl.nextl]; if (t1->op==CON) { if (t1->value==0) return(t1); if (op==TIMES && t1->value==1 && acl.nextl>0) if (--acl.nextl <= 0)  return(acl.llist[0]); } } if (op==PLUS && !flt) distrib(&acl); tree = *(t2 = &acl.llist[0]); d = max(degree(tree), islong(tree->type)); if (op==TIMES && !flt) d++; for (i=0; itr2 = t = *++t2; d1 = degree(t); /* * PDP-11 strangeness: * rt. op of ^ must be in a register. */ if (op==EXOR && dcalc(t, 0)<=12) { t1->tr2 = t = optim(tnode(LOAD, t->type, t)); d1 = t->degree; } t1->degree = d = d==d1? d+islong(t1->type): max(d, d1); t1->tr1 = tree; tree = t1; if (tree->type==LONG) { if (tree->op==TIMES) tree = hardlongs(tree); else if (tree->op==PLUS && (t = isconstant(tree->tr1)) && t->value < 0) { tree->op = MINUS; t->value = - t->value; t = tree->tr1; tree->tr1 = tree->tr2; tree->tr2 = t; } } } if (tree->op==TIMES && ispow2(tree)) tree->degree = max(degree(tree->tr1), islong(tree->type)); return(tree); } distrib(list) struct acl *list; { /* * Find a list member of the form c1c2*x such * that c1c2 divides no other such constant, is divided by * at least one other (say in the form c1*y), and which has * fewest divisors. Reduce this pair to c1*(y+c2*x) * and iterate until no reductions occur. */ register struct tnode **p1, **p2; struct tnode *t; int ndmaj, ndmin; struct tnode **dividend, **divisor; struct tnode **maxnod, **mindiv; loop: maxnod = &list->llist[list->nextl]; ndmaj = 1000; dividend = 0; for (p1 = list->llist; p1 <= maxnod; p1++) { if ((*p1)->op!=TIMES || (*p1)->tr2->op!=CON) continue; ndmin = 0; for (p2 = list->llist; p2 <= maxnod; p2++) { if (p1==p2 || (*p2)->op!=TIMES || (*p2)->tr2->op!=CON) continue; if ((*p1)->tr2->value == (*p2)->tr2->value) { (*p2)->tr2 = (*p1)->tr1; (*p2)->op = PLUS; (*p1)->tr1 = (*p2); *p1 = optim(*p1); squash(p2, maxnod); list->nextl--; goto loop; } if (((*p2)->tr2->value % (*p1)->tr2->value) == 0) goto contmaj; if (((*p1)->tr2->value % (*p2)->tr2->value) == 0) {  ndmin++; mindiv = p2; } } if (ndmin > 0 && ndmin < ndmaj) { ndmaj = ndmin; dividend = p1; divisor = mindiv; } contmaj:; } if (dividend==0) return; t = list->nlist[--list->nextn]; p1 = dividend; p2 = divisor; t->op = PLUS; t->type = (*p1)->type; t->tr1 = (*p1); t->tr2 = (*p2)->tr1; (*p1)->tr2->value =/ (*p2)->tr2->value; (*p2)->tr1 = t; t = optim(*p2); if (p1 < p2) { *p1 = t; squash(p2, maxnod); } else { *p2 = t; squash(p1, maxnod); } list->nextl--; goto loop; } squash(p, maxp) struct tnode **p, **maxp; { register struct tnode **np; for (np = p; np < maxp; np++) *np = *(np+1); } const(op, vp, av) int *vp; { register int v; v = av; switch (op) { case PLUS: *vp =+ v; return; case TIMES: *vp =* v; return; case AND: *vp =& v; return; case OR: *vp =| v; return; case EXOR: *vp =^ v; return; case DIVIDE: case MOD: if (v==0) error("Divide check"); else if (op==DIVIDE) *vp =/ v; else *vp =% v; return; case RSHIFT: *vp =>> v; return; case LSHIFT: *vp =<< v; return; case NAND: *vp =& ~ v; return; } error("C error: const"); } insert(op, atree, alist) struct acl *alist; { register d; register struct acl *list; register struct tnode *tree; int d1, i; struct tnode *t; tree = atree; list = alist; if (tree->op == op) { ins: list->nlist[list->nextn++] = tree; insert(op, tree->tr1, list); insert(op, tree->tr2, list); return; } tree = optim(tree); if (tree->op == op) goto ins; if (!isfloat(tree)) { /* c1*(x+c2) -> c1*x+c1*c2 */ if ((tree->op==TIMES||tree->op==LSHIFT) && tree->tr2->op==CON && tree->tr2->value>0 && tree->tr1->op==PLUS && tree->tr1->tr2->op==CON) { d = tree->tr2->value; if (tree->op==TIMES) tree->tr2->value =* tree->tr1->tr2->value; else tree->tr2->value = tree->tr1->tr2->value << d; tree->tr1->tr2->value = d; tree->tr1->op = tree->op; tree->op = PLUS; if (op==PLUS) goto ins; } } d = degree(tree); for (i=0; inextl; i++) { if ((d1=degree(list->llist[i]))llist[i]; list->llist[i] = tree; tree = t; d = d1; } } list->llist[list->nextl++] = tree; } tnode(op, type, tr1, tr2) struct tnode *tr1, *tr2; { register struct tnode *p; p = getblk(sizeof(*p)); p->op = op; p->type = type; p->degree = 0; p->tr1 = tr1; if (opdope[op]&BINARY) p->tr2 = tr2; else p->tr2 = NULL; return(p); } tconst(val) { register struct tconst *p; p = getblk(sizeof(*p)); p->op = CON; p->type = INT; p->value = val; return(p); } getblk(size) { register *p; if (size&01) abort(); p = curbase; if ((curbase =+ size) >= coremax) { if (sbrk(1024) == -1) { error("Out of space-- pass 2"); exit(1); } coremax =+ 1024; } return(p); } islong(t) { if (t==LONG) return(2); return(1); } isconstant(at) struct tnode *at; { register struct tnode *t; t = at; if (t->op==CON || t->op==SFCON) return(t); if (t->op==ITOL && t->tr1->op==CON) return(t->tr1); return(0); } hardlongs(at) struct tnode *at; { register struct tnode *t; t = at; switch(t->op) { case TIMES: case DIVIDE: case MOD: t->op =+ LTIMES-TIMES; break; case ASTIMES: case ASDIV: case ASMOD: t->op =+ LASTIMES-ASTIMES; t->tr1 = tnode(AMPER, LONG+PTR, t->tr1); break; default: return(t); } return(optim(t)); } nt(at) struct tnode *at; { register struct tnode *t; t = at; if (t->op==CON || t->op==SFCON) return(t); if (t->op==ITOL && t->tr1->op==CON) return(t->tr1); return(0); } hardlo:<w B  _N _N%    5%    _N5 R_N%2 HU&& %2@ & ; % R2*. 5(@% fex @AA p :7 y 5 %  ,_N5@!  !r%/_N7&& %2 2 25M 5& * 5% u-%% r %% % %$%    & 5  | & 5_0% M A p _N% , N _N _J   _N_ _JNf 2_J% %_Nee% _N3% c% %.%L%% % %2_%%e& %%u- @mNf 2  r eNA! y4ww C  _( 3_p%e2 _(%$2  (& ( e2 _(%:_(_/30-1t 1 _(.3 /30A1t A1 _(%$_(%)%&( e3 3 344  _(_%#_(% 4_(% %%%2-%  _(%(4%1-%2l_(%# `t_(a 5[ U%3  #_(%:4 :_f%%<%4x4x_(% 4x_(%   4t]  r eA! y%;1 4C@ 4<47 e    L 7 3 7  y   & 3ww DT L2 1t 1t2 22 3 (& x &&  e&&  e   r eA! yr ww b5 5 B 5Nef % C Cae !u %% ef % %(%0.     _ %(%%# A1l +%*%/#@ @a% _ %*%   @_ %( Ne Ce  x & 5%*  5 u-_ @ @ae54N 5%1  f % N@&j % 54@5u- @mNf 54%+%* #%(  5@ )@AA pr _ %*   & 2w w @ @me,55 De,D-_ %*_ %f5 Ce,C-N I%*E%@Ap,p( N AA 2r #AA 2r  e u-u5ue SA1@ @m5DC(@p@0@pAf r2p 5 LN KN& _ w=x@8  %+A r=A r} &@t=@t==A (  x6 wpw lBCJ- `f %f %_ J- H%*%.B%> 9%(5%/%*eAfVp^ AADtp0(%( 5 " @ `, 5!@ `5,@ `,BD  `,ww  LLt4 t@ 5t 4 ww  L4 tww 5 wm- %  enwfw b%wJw FD%% %:% ww De(e# %4  V7< y  w )M8Zfpx  pppp4444PP nz%&3#'(#'*zzzz8zzzzz  N` l*+,HIJUnimplemented field operatorDivide checkC error: constOut of space-- pass 2 xyyy x    yxy       xx   )IIYIH xY   _maprel _notrel _nreg _isn _namsiz _line _ascbuf _nerror _cctab _efftab _regtab _sptab _lsptab _instab _brancht _opdope _opntab _nstack _nfloat _funcbas _curbase _coremax _eolflg _czero _cone _fczero _xlab1 _xlab2 _xop _xzero _optim"~optimcsv tdopetreed1d2opatreeL2L1NL3"L4BL5xL6rL7_unoptim"RL8L10(L11_tnode"L98L12L13L14_isconst"L15$L16L17$L10001:L10002BL100030L18Z_lvfield",L19_acommut" L20xL21L22L23Z_degree L10004L24L25Z_dcalc L10005:_islong"_max L270L28L29L30L31L32L33L34L35L36L26JL37L38L39L40L41L42L434L444L454L464L47PL48PL49PL50n_hardlon"L51L52pL53pL54pL55pL56L57L10006L58_const" L59L10007L10008(L10011NL10010BL10017L10012ZL10013fL10014pL10015xL10016cret ~unoptimRL61subtreptreefpfvatreeL62fL60(L63fL65pL66zL67L68_tconst"(L69L64L70L71 L72nL73|L74L75L76L77 L10018L78XL10019LL10020PL79L80L81L82L83L84L85L86L87 L886L89NL90nL10023L10022L10026L10024L10025L91L93L94L95L96L97_getblk"LL92L10028L10029L10030~lvfield,tt1t2atL100L1018L102zL103zL104zL105zL106zL107zL108zL109zL110zL98 L99L10033L10032L10036L10034L10035L111r_error ~acommut aclfltdittreed1t1t2opatree_isfloat _insert"L113 L114Z L115 L116 L10037 L117 L118 L119 L112 L120 L121X L10038 L122X L123X L1240 L125X L126X L127p _distrib" L128 L129 L130 L132& L10039< L10040J L133 L134p L135 L136 L131 L137 _ispow2 ~distrib maxnodmindivtlistp1p2divisorndmajndmindividendL139 L140" L141 L142 L143N L144 L145 L146 _squash" L147 L148 L149 L138 L150 L151 ~squash pmaxpnpL153 L154 L155 L152 ~const vavopvpL158tL159 L156L160 L161L162 L163L164L165L166*L167L168LL169@L170LL171NL172`L173lL157L100426L174~insertdittreelistd1opatreealistL176L177L175L178L10043L179L180PL181fL182L183L185L184~tnodeptypeoptr1tr2 L187L188 L186$~tconst(valpL189H~getblkLpsizeL191\_abort L192_sbrk L193L194_exit L190~islongtL196L195~isconsttatL10044L198L197L199~hardlontatL202L203L204L205L201.L206L207L208L209L2006L10046VL10047bL10048&fltused nst(valpL189H~get/* * C second pass -- tables */ #include "c1.h" /* * Operator dope table-- see description in c0. */ int opdope[] { 000000, /* EOF */ 000000, /* ; */ 000000, /* { */ 000000, /* } */ 036000, /* [ */ 002000, /* ] */ 036000, /* ( */ 002000, /* ) */ 014201, /* : */ 007001, /* , */ 000000, /* field selection */ 000000, /* reverse field selection */ 000001, /* temporary field selection */ 000001, /* int->ptr */ 000001, /* ptr->int */ 000001, /* long->ptr */ 000001, /* field assignment */ 000000, /* 17 */ 000000, /* 18 */ 000000, /* 19 */ 000400, /* name */ 000400, /* short constant */ 000400, /* string */ 000400, /* float */ 000400, /* double */ 0000400, /* long const */ 000400, /* long const <= 16 bits */ 000400, /* autoi, *r++ */ 000400, /* autod, *--r */ 000000, /* 29 */ 034203, /* ++pre */ 034203, /* --pre */ 034203, /* ++post */ 034203, /* --post */ 034220, /* !un */ 034202, /* &un */ 034220, /* *un */ 034200, /* -un */ 034220, /* ~un */ 036001, /* . (structure reference) */ 030101, /* + */ 030001, /* - */ 032101, /* * */ 032001, /* / */ 032001, /* % */ 026061, /* >> */ 026061, /* << */ 020161, /* & */ 016161, /* | */ 016161, /* ^ */ 036001, /* -> */ 001000, /* int -> double */ 001000, /* double -> int */ 000001, /* && */ 000001, /* || */ 030001, /* &~ */ 001000, /* double -> long */ 001000, /* long -> double */ 001000, /* integer -> long */ 000000, /* long -> integer */ 022005, /* == */ 022005, /* != */ 024005, /* <= */ 024005, /* < */ 024005, /* >= */ 024005, /* > */ 024005, /*

p */ 024005, /* >=p */ 012213, /* =+ */ 012213, /* =- */ 012213, /* =* */ 012213, /* =/ */ 012213, /* =% */ 012253, /* =>> */ 012253, /* =<< */ 012253, /* =& */ 012253, /* =| */ 012253, /* =^ */ 012213, /* = */ 030001, /* & for tests */ 032001, /* * (long) */ 032001, /* / (long) */ 032001, /* % (long) */ 012253, /* =& ~ */ 012213, /* =* (long) */ 012213, /* / (long) */ 012213, /* % (long) */ 000000, /* 89 */  014201, /* ? */ 026061, /* long << */ 012253, /* long =<< */ 000101, /* max */ 000101, /* maxp */ 000101, /* min */ 000101, /* minp */ 000001, /* , */ 000000, /* 98 */ 000000, /* 99 */ 036001, /* call */ 036000, /* mcall */ 000000, /* goto */ 000000, /* jump cond */ 000000, /* branch cond */ 000400, /* set nregs */ 000000, /* 106 */ 000000, /* 107 */ 000000, /* 108 */ 000000, /* 109 */ 000000 /* force r0 */ }; char *opntab[] { 0, 0, 0, 0, 0, 0, 0, 0, ":", ",", "field select", 0, 0, "int->ptr", "ptr->int", "long->ptr", "field assign", 0, 0, 0, "name", "short constant", "string", "float", "double", "long constant", "long constant", "*r++", "*--r", 0, "++pre", "--pre", "++post", "--post", "!un", "&", "*", "-", "~", ".", "+", "-", "*", "/", "%", ">>", "<<", "&", "|", "^", "->", "int->double", "double->int", "&&", "||", "&~", "double->long", "long->double", "integer->long", "long->integer", "==", "!=", "<=", "<", ">=", ">", "<p", "<=p", ">p", ">=p", "=+", "=-", "=*", "=/", "=%", "=>>", "=<<", "=&", "=|", "=^", "=", "& for tests", "*", "/", "%", "=& ~", "=*", "=/", "=%", 0, "?", "<<", "=<<", "\\/", "\\/", "/\\", "/\\", 0, "call", "call", "call", 0, "goto", "jump cond", "branch cond", "set nregs", "load value", 0, 0, 0, "force register" }; /* * Strings for instruction tables. */ char mov[] "mov"; char clr[] "clr"; char cmp[] "cmp"; char tst[] "tst"; char add[] "add"; char sub[] "sub"; char inc[] "inc"; char dec[] "dec"; char mul[] "mul"; char div[] "div"; char asr[] "asr"; char ash[] "ash"; char asl[] "asl"; char bic[] "bic"; char bic1[] "bic $1,"; char bit[] "bit"; char bit1[] "bit $1,"; char bis[] "bis"; char bis1[] "bis $1,"; char xor[] "xor"; char neg[] "neg"; char com[] "com"; char stdol[] "*$"; char ashc[] "ashc"; char slmul[] "lmul"; char sldiv[] "ldiv"; char slrem[] "lrem"; char almul[] "almul"; char aldiv[] "aldiv"; char alrem[] "alrem"; char jeq[] "jeq"; char jne[] "jne"; char jle[] "jle"; char jgt[] "jgt"; char jlt[] "jlt"; char jge[] "jge"; char jlos[] "jlos"; char jhi[] "jhi"; char jlo[] "jlo"; char jhis[] "jhis"; char nop[] "/nop"; char jbr[] "jbr"; /* * Instruction tables, accessed by * I (first operand) or I' (second) macros. */ struct instab instab[] { LOAD, mov, tst, ASSIGN, mov, clr, EQUAL, cmp, tst, NEQUAL, cmp, tst, LESSEQ, cmp, tst, LESS, cmp, tst, GREATEQ,cmp, tst, GREAT, cmp, tst, LESSEQP,cmp, tst, LESSP, cmp, tst, GREATQP,cmp, tst, GREATP, cmp, tst, PLUS, add, inc, ASPLUS, add, inc, MINUS, sub, dec, ASMINUS,sub, dec, INCBEF, add, inc, DECBEF, sub, dec, INCAFT, add, inc, DECAFT, sub, dec, TIMES, mul, mul, ASTIMES,mul, mul, DIVIDE, div, div, ASDIV, div, div, MOD, div, div, ASMOD, div, div, PTOI, div, div, RSHIFT, ash, asr, ASRSH, ash, asr, LSHIFT, ash, asl, ASLSH, ash, asl, AND, bic, bic1, NAND, bic, bic1, ASNAND, bic, bic1, TAND, bit, bit1, OR, bis, bis1, ASOR, bis, bis1, EXOR, xor, xor, ASXOR, xor, xor, NEG, neg, neg, COMPL, com, com, CALL1, stdol, stdol, CALL2, "", "", LLSHIFT,ashc, ashc, ASLSHL, ashc, ashc, LTIMES, slmul, slmul, LDIV, sldiv, sldiv, LMOD, slrem, slrem, LASTIMES,almul, almul, LASDIV, aldiv, aldiv, LASMOD, alrem, alrem, 0, 0, 0}; /* * Similar table for relationals. * The first string is for the positive * test, the second for the inverted one. * The '200+' entries are * used in tests against 0 where a 'tst' * instruction is used; it clears the c-bit * the c-bit so ptr tests are funny. */ struct instab branchtab[] { EQUAL, jeq, jne, NEQUAL, jne, jeq, LESSEQ, jle, jgt, LESS, jlt, jge, GREATEQ,jge, jlt, GREAT, jgt, jle, LESSEQP,jlos, jhi, LESSP, jlo, jhis, GREATQP,jhis, jlo, GREATP, jhi, jlos, 200+EQUAL, jeq, jne, 200+NEQUAL, jne, jeq, 200+LESSEQ, jle, jgt, 200+LESS, jlt, jge, 200+GREATEQ, jge, jlt, 200+GREAT, jgt, jle, 200+LESSEQP, jeq, jne, 200+LESSP, nop, jbr, 200+GREATQP, jbr, nop, 200+GREATP, jne, jeq, 0, 0, 0 }; ars the c-bit * the c-bit so ptr tests are funny. * <<888888888KT]gty!$1>LZ]`cehjmqtx{~movclrcmptstaddsubincdecmuldivasrashaslbicbic $1,bitbit $1,bisbis $1,xornegcom*$ashclmulldivlremalmulaldivalremjeqjnejlejgtjltjgejlosjhijlojhis/nopjbrjP<=>?@ABCDE(F)G !*H+I,J-K.L/7UQ0 N 1O%&b  c[$$\$$R**S00T66V<<WBBXHH<NR=RN>VZ?^b@b^AZVBflCptDtpElfNRRNVZ^bb^ ZV NR z z RN:,field selectint->ptrptr->intlong->ptrfield assignnameshort constantstringfloatdoublelong constantlong constant*r++*--r++pre--pre++post--post!un&*-~.+-*/%>><<&|^->int->doubledouble->int&&||&~double->longlong->doubleinteger->longlong->integer==!=<=<>=>p>=p=+=-=*=/=%=>>=<<=&=|=^=& for tests*/%=& ~=*=/=%?<<=<<\/\//\/\callcallcallgotojump condbranch condset nregsload valueforce register_maprel _notrel _nreg _isn _namsiz _line _ascbuf _nerror _cctab _efftab _regtab _sptab _lsptab _instab#_brancht#_opdope#_opntab#_nstack _nfloat _funcbas _curbase _coremax _eolflg _czero _cone _fczero _xlab1 _xlab2 _xop _xzero L1:L2<L3>L4KL5TL6]L7gL8tL9yL10L11L12L13L14L15L16L17L18L19L20L21L22L23L24L25L26L27L28L29L30L31L32L33L34L35L36L37L38L39L40L41L42!L43$L441L45>L46LL47ZL48]L49`L50cL51eL52hL53jL54mL55qL56tL57xL58{L59~L60L61L62L63L64L65L66L67L68L69L70L71L72L73L74L75L76L77L78L79L80L81L82L83L84L85L86L87L88L89L90L91_mov#_clr#_cmp#_tst#_add#_sub#_inc#_dec#_mul#_div#_asr#_ash#_asl#_bic#_bic1#_bit#_bit1#_bis#_bis1# _xor#_neg#_com#_stdol# _ashc#$_slmul#*_sldiv#0_slrem#6_almul#<_aldiv#B_alrem#H_jeq#N_jne#R_jle#V_jgt#Z_jlt#^_jge#b_jlos#f_jhi#l_jlo#p_jhis#t_nop#z_jbr#L134L135#_cmp#_tst#_add#_sub#_inc#_dec#_mul#_div#_asr#_ash#_asl#_bic#_bic1#_bit#_bit1#_bis#_bis1# _xor#_neg#_com#_stdol# _ashc#$_slmul#*_sldiv#0_slrem#6_almul#<_aldiv#B_alrem#H_jeq#N_jne#R_jle#V_jgt#Z_jlt#^_jge#b_jlos#f_jhi#l_jlo#p_jhis#t_nop#z_jbr#L134/* * Header for object code improver */ #define JBR 1 #define CBR 2 #define JMP 3 #define LABEL 4 #define DLABEL 5 #define EROU 7 #define JSW 9 #define MOV 10 #define CLR 11 #define COM 12 #define INC 13 #define DEC 14 #define NEG 15 #define TST 16 #define ASR 17 #define ASL 18 #define SXT 19 #define CMP 20 #define ADD 21 #define SUB 22 #define BIT 23 #define BIC 24 #define BIS 25 #define MUL 26 #define DIV 27 #define ASH 28 #define XOR 29 #define TEXT 30 #define DATA 31 #define BSS 32 #define EVEN 33 #define MOVF 34 #define MOVOF 35 #define MOVFO 36 #define ADDF 37 #define SUBF 38 #define DIVF 39 #define MULF 40 #define CLRF 41 #define CMPF 42 #define NEGF 43 #define TSTF 44 #define CFCC 45 #define SOB 46 #define JSR 47 #define END 48 #define JEQ 0 #define JNE 1 #define JLE 2 #define JGE 3 #define JLT 4 #define JGT 5 #define JLO 6 #define JHI 7 #define JLOS 8 #define JHIS 9 #define BYTE 100 struct node { char op; char subop; struct node *forw; struct node *back; struct node *ref; int labno; char *code; int refc; }; struct { int combop; }; struct optab { char *opstring; int opcode; } optab[]; char line[512]; struct node first; char *curlp; int nbrbr; int nsaddr; int redunm; int iaftbr; int njp1; int nrlab; int nxjump; int ncmot; int nrevbr; int loopiv; int nredunj; int nskip; int ncomj; int nsob; int nrtst; int nlit; int nchange; int isn; int debug; char *lasta; char *lastr; char *firstr; char revbr[]; char regs[12][20]; char conloc[20]; char conval[20]; char ccloc[20]; #define RT1 10 #define RT2 11 #define FREG 5 #define NREG 5 #define LABHS 127 #define OPHS 57 struct optab *ophash[OPHS]; struct { char lbyte; }; node first; char *curlp; int nbrbr; int nsaddr; int redunm; int iaftbr; int njp1; int nrlab; int nxjump; int ncmot; int nrevbr; int loopiv; int nredunj; int nskip; int ncomj; int nsob; int nrtst; int nlit; int nchange; int isn; int debug; char *lasta; char *lastr; char *firstr; char revbr[]; char regs[12][20]; char conloc[20]; char conval[20]; char ccloc[20]; #define RT1 10 #def# /* * C object code improver */ #include "c2.h" struct optab optab[] { "jbr", JBR, "jeq", CBR | JEQ<<8, "jne", CBR | JNE<<8, "jle", CBR | JLE<<8, "jge", CBR | JGE<<8, "jlt", CBR | JLT<<8, "jgt", CBR | JGT<<8, "jlo", CBR | JLO<<8, "jhi", CBR | JHI<<8, "jlos", CBR | JLOS<<8, "jhis", CBR | JHIS<<8, "jmp", JMP, ".globl",EROU, "mov", MOV, "clr", CLR, "com", COM, "inc", INC, "dec", DEC, "neg", NEG, "tst", TST, "asr", ASR, "asl", ASL, "sxt", SXT, "cmp", CMP, "add", ADD, "sub", SUB,  "bit", BIT, "bic", BIC, "bis", BIS, "mul", MUL, "ash", ASH, "xor", XOR, ".text",TEXT, ".data",DATA, ".bss", BSS, ".even",EVEN, "movf", MOVF, "movof",MOVOF, "movfo",MOVFO, "addf", ADDF, "subf", SUBF, "divf", DIVF, "mulf", MULF, "clrf", CLRF, "cmpf", CMPF, "negf", NEGF, "tstf", TSTF, "cfcc", CFCC, "sob", SOB, "jsr", JSR, ".end", END, 0, 0}; char revbr[] { JNE, JEQ, JGT, JLT, JGE, JLE, JHIS, JLOS, JHI, JLO }; int isn 20000; main(argc, argv) char **argv; { register int niter, maxiter, isend; extern end; extern fin, fout; int nflag; if (argc>1 && argv[1][0]=='+') { argc--; argv++; debug++; } nflag = 0; if (argc>1 && argv[1][0]=='-') { argc--; argv++; nflag++; } if (argc>1) { if ((fin = open(argv[1], 0)) < 0) { printf("C2: can't find %s\n", argv[1]); exit(1); } } else fin = dup(0); if (argc>2) { if ((fout = creat(argv[2], 0666)) < 0) { fout = 1; printf("C2: can't create %s\n", argv[2]); exit(1); } } else fout = dup(1); lasta = firstr = lastr = sbrk(2); maxiter = 0; opsetup(); do { isend = input(); movedat(); niter = 0; do { refcount(); do { iterate(); clearreg(); niter++; } while (nchange); comjump(); rmove(); } while (nchange || jumpsw()); addsob(); output(); if (niter > maxiter) maxiter = niter; lasta = firstr; } while (isend); flush(); fout = 2; if (nflag) { printf("%d iterations\n", maxiter); printf("%d jumps to jumps\n", nbrbr); printf("%d inst. after jumps\n", iaftbr);  printf("%d jumps to .+2\n", njp1); printf("%d redundant labels\n", nrlab); printf("%d cross-jumps\n", nxjump); printf("%d code motions\n", ncmot); printf("%d branches reversed\n", nrevbr); printf("%d redundant moves\n", redunm); printf("%d simplified addresses\n", nsaddr); printf("%d loops inverted\n", loopiv); printf("%d redundant jumps\n", nredunj); printf("%d common seqs before jmp's\n", ncomj); printf("%d skips over jumps\n", nskip); printf("%d sob's added\n", nsob); printf("%d redundant tst's\n", nrtst); printf("%d literals eliminated\n", nlit); printf("%dK core\n", ((lastr+01777)>>10)&077); flush(); } exit(0); } input() { register struct node *p, *lastp; register int op; lastp = &first; for (;;) { op = getline(); switch (op.op) { case LABEL: p = alloc(sizeof first); if (line[0] == 'L') { p->combop = LABEL; p->labno = getnum(line+1); p->code = 0; } else { p->combop = DLABEL; p->labno = 0; p->code = copy(line); } break;  case JBR: case CBR: case JMP: case JSW: p = alloc(sizeof first); p->combop = op; if (*curlp=='L' && (p->labno = getnum(curlp+1))) p->code = 0; else { p->labno = 0; p->code = copy(curlp); } break; default: p = alloc(sizeof first); p->combop = op; p->labno = 0; p->code = copy(curlp); break; } p->forw = 0; p->back = lastp; lastp->forw = p; lastp = p; p->ref = 0; if (op==EROU) return(1); if (op==END) return(0); } } getline() { register char *lp; register c; lp = line; while (c = getchar()) { if (c==':') { *lp++ = 0; return(LABEL); } if (c=='\n') { *lp++ = 0; return(oplook()); } *lp++ = c; } *lp++ = 0; return(END); } getnum(ap) char *ap; { register char *p; register n, c; p = ap; n = 0; while ((c = *p++) >= '0' && c <= '9') n = n*10 + c - '0'; if (*--p != 0) return(0); return(n); } output() { register struct node *t; register struct optab *op; register int byte; t = &first; while (t = t->forw) switch (t->op) { case END: return; case LABEL: printf("L%d:", t->labno); continue; case DLABEL: printf("%s:", t->code); continue; default: if ((byte = t->subop) == BYTE) t->subop = 0; for (op = optab; op->opstring!=0; op++) if (op->opcode == t->combop) { printf("%s", op->opstring); if (byte==BYTE) printf("b"); break; } if (t->code) { reducelit(t); printf("\t%s\n", t->code); } else if (t->op==JBR || t->op==CBR) printf("\tL%d\n", t->labno); else printf("\n"); continue; case JSW: printf("L%d\n", t->labno); continue; case SOB: printf("sob %s,L%d\n", t->code, t->labno); continue; case 0: if (t->code) printf("%s", t->code); printf("\n"); continue; } } /* * Notice addresses of the form * $xx,xx(r) * and replace them with (pc),xx(r) * -- Thanx and a tip of the Hatlo hat to Bliss-11. */ reducelit(at) struct node *at; { register char *c1, *c2; char *c2s; register struct node *t; t = at; if (*t->code != '$') return; c1 = t->code; while (*c1 != ',') if (*c1++ == '\0') return; c2s = c1; c1++; if (*c1=='*') c1++; c2 = t->code+1; while (*c1++ == *c2++); if (*--c1!='(' || *--c2!=',') return; t->code = copy("(pc)", c2s); nlit++; } copy(ap) char *ap; { register char *p, *np; char *onp; register n; int na; na = nargs(); p = ap; n = 0; if (*p==0) return(0); do n++; while (*p++); if (na>1) { p = (&ap)[1]; while (*p++) n++; } onp = np = alloc(n); p = ap; while (*np++ = *p++); if (na>1) { p = (&ap)[1]; np--; while (*np++ = *p++); } return(onp); } opsetup() { register struct optab *optp, **ophp; register char *p; for (optp = optab; p = optp->opstring; optp++) { ophp = &ophash[(((p[0]<<3)+(p[1]<<1)+p[2])&077777) % OPHS]; while (*ophp++) if (ophp > &ophash[OPHS]) ophp = ophash; *--ophp = optp; } } oplook() { register struct optab *optp; register char *lp, *op; static char tmpop[32]; struct optab **ophp; op = tmpop; for (lp = line; *lp && *lp!=' ' && *lp!='\t';) *op++ = *lp++; *op++ = 0; while (*lp=='\t' || *lp==' ') lp++; curlp = lp; ophp = &ophash[(((tmpop[0]<<3)+(tmpop[1]<<1)+tmpop[2])&077777) % OPHS]; while (optp = *ophp) { op = optp->opstring; lp = tmpop; while (*lp == *op++) if (*lp++ == 0) return(optp->opcode); if (*lp++=='b' && *lp++==0 && *--op==0) return(optp->opcode + (BYTE<<8)); ophp++; if (ophp >= &ophash[OPHS]) ophp = ophash; } if (line[0]=='L') { lp = &line[1]; while (*lp) if (*lp<'0' || *lp++>'9') return(0); curlp = line; return(JSW); } curlp = line; return(0); } refcount() { register struct node *p, *lp; static struct node *labhash[LABHS]; register struct node **hp; for (hp = labhash; hp < &labhash[LABHS];) *hp++ = 0; for (p = first.forw; p!=0; p = p->forw) if (p->op==LABEL) { labhash[p->labno % LABHS] = p; p->refc = 0; } for (p = first.forw; p!=0; p = p->forw) { if (p->op==JBR || p->op==CBR || p->op==JSW) { p->ref = 0; lp = labhash[p->labno % LABHS]; if (lp==0 || p->labno!=lp->labno) for (lp = first.forw; lp!=0; lp = lp->forw) { if (lp->op==LABEL && p->labno==lp->labno) break; } if (lp) { hp = nonlab(lp)->back; if (hp!=lp) { p->labno = hp->labno; lp = hp; } p->ref = lp; lp->refc++; } } } for (p = first.forw; p!=0; p = p->forw) if (p->op==LABEL && p->refc==0 && (lp = nonlab(p))->op && lp->op!=JSW) decref(p); } iterate() { register struct node *p, *rp, *p1; nchange = 0; for (p = first.forw; p!=0; p = p->forw) { if ((p->op==JBR||p->op==CBR||p->op==JSW) && p->ref) { rp = nonlab(p->ref); if (rp->op==JBR && rp->labno && p!=rp) { nbrbr++; p->labno = rp->labno; decref(p->ref); rp->ref->refc++; p->ref = rp->ref; nchange++; } } if (p->op==CBR && (p1 = p->forw)->op==JBR) { rp = p->ref; do rp = rp->back; while (rp->op==LABEL); if (rp==p1) { decref(p->ref); p->ref = p1->ref; p->labno = p1->labno; p1->forw->back = p; p->forw = p1->forw; p->subop = revbr[p->subop]; nchange++; nskip++; } } if (p->op==JBR || p->op==JMP) { while (p->forw && p->forw->op!=LABEL && p->forw->op!=EROU && p->forw->op!=END && p->forw->op!=0 && p->forw->op!=DATA) { nchange++; iaftbr++; if (p->forw->ref) decref(p->forw->ref); p->forw = p->forw->forw; p->forw->back = p; } rp = p->forw; while (rp && rp->op==LABEL) { if (p->ref == rp) { p->back->forw = p->forw; p->forw->back = p->back; p = p->back; decref(rp); nchange++; njp1++; break; } rp = rp->forw; } xjump(p); p = codemove(p); } } } xjump(ap) { register int *p1, *p2, *p3; int nxj; nxj = 0; p1 = ap; if ((p2 = p1->ref)==0) return(0); for (;;) { while ((p1 = p1->back) && p1->op==LABEL); while ((p2 = p2->back) && p2->op==LABEL); if (!equop(p1, p2) || p1==p2) return(nxj); p3 = insertl(p2); p1->combop = JBR; p1->ref = p3; p1->labno = p3->labno; p1->code = 0; nxj++; nxjump++; nchange++; } } insertl(ap) struct node *ap; { register struct node *lp, *op; op = ap; if (op->op == LABEL) { op->refc++; return(op); } if (op->back->op == LABEL) { op = op->back; op->refc++; return(op); } lp = alloc(sizeof first); lp->combop = LABEL; lp->labno = isn++; lp->ref = 0; lp->code = 0; lp->refc = 1; lp->back = op->back; lp->forw = op; op->back->forw = lp; op->back = lp; return(lp); } codemove(ap) struct node *ap; { register struct node *p1, *p2, *p3; struct node *t, *tl; int n; p1 = ap; if (p1->op!=JBR || (p2 = p1->ref)==0) return(p1); while (p2->op == LABEL) if ((p2 = p2->back) == 0) return(p1); if (p2->op!=JBR && p2->op!=JMP) goto ivloop; p2 = p2->forw; p3 = p1->ref; while (p3) { if (p3->op==JBR || p3->op==JMP) { if (p1==p3) return(p1); ncmot++; nchange++; p1->back->forw = p2; p1->forw->back = p3; p2->back->forw = p3->forw; p3->forw->back = p2->back; p2->back = p1->back; p3->forw = p1->forw; decref(p1->ref); return(p2); } else p3 = p3->forw; } return(p1); ivloop: if (p1->forw->op!=LABEL) return(p1); p3 = p2 = p2->forw; n = 16; do { if ((p3 = p3->forw) == 0 || p3==p1 || --n==0) return(p1); } while (p3->op!=CBR || p3->labno!=p1->forw->labno); do if ((p1 = p1->back) == 0) return(ap); while (p1!=p3); p1 = ap; tl = insertl(p1); p3->subop = revbr[p3->subop]; decref(p3->ref); p2->back->forw = p1; p3->forw->back = p1; p1->back->forw = p2; p1->forw->back = p3; t = p1->back; p1->back = p2->back; p2->back = t; t = p1->forw; p1->forw = p3->forw; p3->forw = t; p2 = insertl(p1->forw); p3->labno = p2->labno; p3->ref = p2; decref(tl); if (tl->refc<=0) nrlab--; loopiv++; nchange++; return(p3); } comjump() { register struct node *p1, *p2, *p3; for (p1 = first.forw; p1!=0; p1 = p1->forw) if (p1->op==JBR && (p2 = p1->ref) && p2->refc > 1) for (p3 = p1->forw; p3!=0; p3 = p3->forw) if (p3->op==JBR && p3->ref == p2) backjmp(p1, p3); } backjmp(ap1, ap2) struct node *ap1, *ap2; { register struct node *p1, *p2, *p3; p1 = ap1; p2 = ap2; for(;;) { while ((p1 = p1->back) && p1->op==LABEL); p2 = p2->back; if (equop(p1, p2)) { p3 = insertl(p1); p2->back->forw = p2->forw; p2->forw->back = p2->back; p2 = p2->forw; decref(p2->ref); p2->labno = p3->labno; p2->ref = p3; nchange++; ncomj++; } else return; } } p3 = p1->forw; p3!=0; p3 = p3->forw) if (p3->op==JBR && p3->ref == p2) backjmp(p1, p3); } backjmp( Hw % @+ e 5 % @- e % @& 7@   7n%@& 7PH@   7  777  X t  z `  *   l    _h ( ; xQ jb \w N @ 2 $      4 D X etEp  ww   5 x  L^ n44 ,w>4  L n4 4  4 4 34 %%0 w %:  Pw% Ԑ 0w D %9 Wp C`e%0 w`w Xj 7B  y z Y %d4   e 3# %d ̥̥&  %    wtw p B$ % ԋ ̥,5 ̥*  Ԥ(, N  2 ww  5D ̋ w ԋ%D ԋ D%D @w  t @`@`E r9C e%r #ew^w Z ˥ ˥ Ҕˋ ˥ ˥ & t @` @`E r9 eu3Ң!ӋӋedˋ˥0ӥ9  wӥbe%rDL~w x %j̥  r 14  B9̥̥̥ .4  r C, ˥,      ̥  ˋ˥   ww 7  _̥̥̥ "  ˥   H   (̥(ʥ#˥  04  ̥/̥,R*&0"   40  ˥ 00 2 .  _zww 5 D w b 4 ̥˥&  @w C˥ % D >4 4  03w:w 6D̥C?<˥˥˥6$ 32   ʥʥ w! ʥ,@ D b 52  005s5r b N @  w ̥%  ʥ &   wjw fDC b   & "̥& w      " & * . 3  8 < C G K O S W [ _ c g k o s w {        ! " # $ % & ' ( ) * + , - . / 0  N .0fHRjbrjeqjnejlejgejltjgtjlojhijlosjhisjmp.globlmovclrcomincdecnegtstasraslsxtcmpaddsubbitbicbismulashxor.text.data.bss.evenmovfmovofmovfoaddfsubfdivfmulfclrfcmpfnegftstfcfccsobjsr.endC2: can't find %s C2: can't create %s %d iterations %d jumps to jumps %d inst. after jumps %d jumps to .+2 %d redundant labels %d cross-jumps %d code motions %d branches reversed %d redundant moves %d simplified addresses %d loops inverted %d redundant jumps %d common seqs before jmp's %d skips over jumps %d sob's added %d redundant tst's %d literals eliminated %dK core L%d:%s:%sb %s L%d L%d sob %s,L%d %s (pc)Yi 8HX x8HXyIIiIyy8I8y888888i8Y888 888)8988HY(  99 9Y YY(888888Y9Y YY999Y))))YI)IIIIyIYI(Y YIIY)YI (_optab# _line _first _curlp _nbrbr _nsaddr _redunm _iaftbr _njp1 _nrlab _nxjump _ncmot _nrevbr _loopiv _nredunj _nskip _ncomj _nsob _nrtst _nlit _nchange _isn# _debug _lasta _lastr _firstr _revbr# _regs _conloc _conval _ccloc _ophash rL1 L2 L3 L4 L5 L6 L7" L8& L9* L10. L113 L128 L13< L14C L15G L16K L17O L18S L19W L20[ L21_ L22c L23g L24k L25o L26s L27w L28{ L29 L30 L31 L32 L33 L34 L35 L36 L37 L38 L39 L40 L41 L42 L43 L44 L45 L46 L47 L48 L49 L50 L51 _main"~maincsv argcargvmaxiternflagisendniterL53(L54NL55_open _fin L58L57 _printf _exit _dup L59_creat _fout L62L61_sbrk _opsetup"RL65_input"r_movedat L68_refcoun"L71 _iterate"n_clearre _comjump"H _rmove _jumpsw _addsob _output"L72>_flush L73hL74L75(L76;L77QL78bL79wL80L81L82L83L84L85L86L87L884L89DL90XL91pcret L10001 L103L97L106~inputrpoplastpL93z_getline"4_alloc L98_getnum"nL20000L95L20002L92L20004 L20006_copy"~getline4clpL110^L20010>L112VL109RL20008L_oplook"_getchar ~getnumncnpapL115L20012zL116L117L114L10004 L10005 L148fL124L126L144HL146RL118L128~outputtbyteopL119L20016L10006L125zL20019L127L129L130L20014_reducel"L138L132L131&L134L136L100028L140BL141L143L20017~L145L147L149zL150L151~reduceltc1c2atc2sL152L153L20024L155L156L158~copyonpnpnaapnp_nargs L163 L159L164&L165"L20026 L1676L169LL170H~opsetupRpophpoptpL173L20030\L176L20028~oplookL180ophpoptplpoptmpopL181L20032L182L183L10007L185nL20037L187L188TL179PL20035L190ZL20039.L1932L194FL10008B~refcounL197plabhashhplpL20041L200L20043L202L2044L20047L10009L2060L10010L208L209 L20045L211_nonlab L213(L214fL20049>L216b_decref ~iteratenpp1rpL219zL218L10012L222L224.L227L230L221L20051<L231L232L233L234L235_xjump"_codemov" ~xjumpnxjp1p2p3apL2402 L236 L244 _insertl"b L242> L243J _equop L10014\ ~insertlb aplpopL246~ L20053p L245 L20055x ~codemov ntp1p2p3aptlL20060^ L250 L20057 L10016 L253d L254J L257 L248` L256F L10017Z L262x L266 L264 L268< ~comjumpH p1p2p3L270 L20064R L272 L274 L20062l L276 _backjmp" ~backjmp p1p2p3ap1ap2L281 L20066 L282 55x ~codemov ntp1p2p3# /* * C object code improver-- second part */ #include "c2.h" rmove() { register struct node *p; register char *cp; register int r; int r1, flt; for (p=first.forw; p!=0; p = p->forw) { if (debug) { for (r=0; r<2*NREG; r++) if (regs[r][0]) printf("%d: %s\n", r, regs[r]); printf("-\n"); } flt = 0; switch (p->op) { case MOVF: case MOVFO: case MOVOF: flt = NREG; case MOV: if (p->subop==BYTE) goto badmov; dualop(p); if ((r = findrand(regs[RT1], flt)) >= 0) { if (r == flt+isreg(regs[RT2]) && p->forw->op!=CBR) { p->forw->back = p->back; p->back->forw = p->forw; redunm++; continue; } } repladdr(p, 0, flt); r = isreg(regs[RT1]); r1 = isreg(regs[RT2]); dest(regs[RT2], flt); if (r >= 0) if (r1 >= 0) savereg(r1+flt, regs[r+flt]); else savereg(r+flt, regs[RT2]); else if (r1 >= 0) savereg(r1+flt, regs[RT1]); else setcon(regs[RT1], regs[RT2]); source(regs[RT1]); setcc(regs[RT2]); continue; case ADDF: case SUBF: case DIVF: case MULF: flt = NREG; case ADD: case SUB: case BIC: case BIS: case MUL: case DIV: case ASH: badmov: dualop(p); repladdr(p, 0, flt); source(regs[RT1]); dest(regs[RT2], flt); if (p->op==DIV && (r = isreg(regs[RT2])>=0)) regs[r+1][0] = 0; ccloc[0] = 0; continue; case CLRF: case NEGF: flt = NREG; case CLR: case COM: case INC: case DEC: case NEG: case ASR: case ASL: case SXT: singop(p); dest(regs[RT1], flt); if (p->op==CLR && flt==0) if ((r = isreg(regs[RT1])) >= 0) savereg(r, "$0"); else setcon("$0", regs[RT1]); ccloc[0] = 0; continue; case TSTF: flt = NREG; case TST: singop(p); repladdr(p, 0, flt); source(regs[RT1]); if (equstr(regs[RT1], ccloc)) { p->back->forw = p->forw; p->forw->back = p->back; p = p->back; nrtst++; nchange++; } continue; case CMPF: flt = NREG; case CMP: case BIT: dualop(p); source(regs[RT1]); source(regs[RT2]); repladdr(p, 1, flt); ccloc[0] = 0; continue; case CBR: case CFCC: ccloc[0] = 0; continue; case JBR: redunbr(p); default: clearreg(); } } } jumpsw() { register struct node *p, *p1; register t; int nj; t = 0; nj = 0; for (p=first.forw; p!=0; p = p->forw) p->refc = ++t; for (p=first.forw; p!=0; p = p1) { p1 = p->forw; if (p->op == CBR && p1->op==JBR && p->ref && p1->ref && abs(p->refc - p->ref->refc) > abs(p1->refc - p1->ref->refc)) { p->subop = revbr[p->subop]; t = p1->ref; p1->ref = p->ref; p->ref = t; t = p1->labno; p1->labno = p->labno; p->labno = t; nrevbr++; nj++; } } return(nj); } addsob() { register struct node *p, *p1; for (p = &first; (p1 = p->forw)!=0; p = p1) { if (p->op==DEC && isreg(p->code)>=0 && p1->combop==(CBR|JNE<<8)) { if (p->refc < p1->ref->refc) continue; if (p->refc - p1->ref->refc > 50) continue; p->labno = p1->labno; p->combop = SOB; p1->forw->back = p; p->forw = p1->forw; nsob++; } } } abs(x) { return(x<0? -x: x); } equop(ap1, p2) struct node *ap1, *p2; { register char *cp1, *cp2; register struct node *p1; p1 = ap1; if (p1->combop != p2->combop) return(0); if (p1->op>0 && p1->opcode; cp2 = p2->code; if (cp1==0 && cp2==0) return(1); if (cp1==0 || cp2==0) return(0); while (*cp1 == *cp2++) if (*cp1++ == 0) return(1); return(0); } decref(ap) { register struct node *p; p = ap; if (--p->refc <= 0) { nrlab++; p->back->forw = p->forw; p->forw->back = p->back; } } nonlab(ap) struct node *ap; { register struct node *p; p = ap; while (p && p->op==LABEL) p = p->forw; return(p); } alloc(an) { register int n; register char *p; n = an; n++; n =& ~01; if (lasta+n >= lastr) { if (sbrk(2000) == -1) { write(2, "Optimizer: out of space\n", 24); exit(1); } lastr =+ 2000; } p = lasta; lasta =+ n; return(p); } clearreg() { register int i; for (i=0; i<2*NREG; i++) regs[i][0] = '\0'; conloc[0] = 0; ccloc[0] = 0; } savereg(ai, as) char *as; { register char *p, *s, *sp; sp = p = regs[ai]; s = as; if (source(s)) return; while (*p++ = *s) { if (s[0]=='(' && s[1]=='r' && s[2]<'5') { *sp = 0; return; } if (*s++ == ',') break; } *--p = '\0'; } dest(as, flt) char *as; { register char *s; register int i; s = as; source(s); if ((i = isreg(s)) >= 0) regs[i+flt][0] = 0; for (i=flt; i= 0) regs[i][0] = 0; while (*s) { if ((*s=='(' && (*(s+1)!='r' || *(s+2)!='5')) || *s++=='*') { for (i=flt; icode; p2 = regs[RT1]; while (*p2++ = *p1++); regs[RT2][0] = 0; } dualop(ap) struct node *ap; { register char *p1, *p2; register struct node *p; p = ap; p1 = p->code; p2 = regs[RT1]; while (*p1 && *p1!=',') *p2++ = *p1++; *p2++ = 0; p2 = regs[RT2]; *p2 = 0; if (*p1++ !=',') return; while (*p2++ = *p1++); } findrand(as, flt) char *as; { register int i; for (i = flt; i='0' && s[1]<='4' && s[2]==0) return(s[1]-'0'); return(-1); } check() { register struct node *p, *lp; lp = &first; for (p=first.forw; p!=0; p = p->forw) { if (p->back != lp) abort(); lp = p; } } source(ap) char *ap; { register char *p1, *p2; p1 = ap; p2 = p1; if (*p1==0) return(0); while (*p2++); if (*p1=='-' && *(p1+1)=='(' || *p1=='*' && *(p1+1)=='-' && *(p1+2)=='(' || *(p2-2)=='+') { while (*p1 && *p1++!='r'); if (*p1>='0' && *p1<='4') regs[*p1 - '0'][0] = 0; return(1); } return(0); } repladdr(p, f, flt) struct node *p; { register r; int r1; register char *p1, *p2; static char rt1[50], rt2[50]; if (f) r1 = findrand(regs[RT2], flt); else r1 = -1; r = findrand(regs[RT1], flt); if (r1 >= NREG) r1 =- NREG; if (r >= NREG) r =- NREG; if (r>=0 || r1>=0) { p2 = regs[RT1]; for (p1 = rt1; *p1++ = *p2++;); if (regs[RT2][0]) { p1 = rt2; *p1++ = ','; for (p2 = regs[RT2]; *p1++ = *p2++;); } else rt2[0] = 0; if (r>=0) { rt1[0] = 'r'; rt1[1] = r + '0'; rt1[2] = 0; nsaddr++; } if (r1>=0) { rt2[1] = 'r'; rt2[2] = r1 + '0'; rt2[3] = 0; nsaddr++; } p->code = copy(rt1, rt2); } } movedat() { register struct node *p1, *p2; struct node *p3; register seg; struct node data; struct node *datp; if (first.forw == 0) return; datp = &data; for (p1 = first.forw; p1!=0; p1 = p1->forw) { if (p1->op == DATA) { p2 = p1->forw; while (p2 && p2->op!=TEXT) p2 = p2->forw; if (p2==0) break; p3 = p1->back; p1->back->forw = p2->forw; p2->forw->back = p3; p2->forw = 0; datp->forw = p1; p1->back = datp; p1 = p3; datp = p2; } } if (data.forw) { datp->forw = first.forw; first.forw->back = datp; data.forw->back = &first; first.forw = data.forw; } seg = -1; for (p1 = first.forw; p1!=0; p1 = p1->forw) { if (p1->op==TEXT||p1->op==DATA||p1->op==BSS) { if (p1->op == seg || p1->forw&&p1->forw->op==seg) { p1->back->forw = p1->forw; p1->forw->back = p1->back; p1 = p1->back; continue; } seg = p1->op; } } } redunbr(ap) struct node *ap; { register struct node *p, *p1; register char *ap1; char *ap2; if ((p1 = p->ref) == 0) return; p1 = nonlab(p1); if (p1->op==TST) { singop(p1); savereg(RT2, "$0"); } else if (p1->op==CMP) dualop(p1); else return; if (p1->forw->op!=CBR) return; ap1 = findcon(RT1); ap2 = findcon(RT2); p1 = p1->forw; if (compare(p1->subop, ap1, ap2)) { nredunj++; nchange++; decref(p->ref); p->ref = p1->ref; p->labno = p1->labno; p->ref->refc++; } } findcon(i) { register char *p; register r; p = regs[i]; if (*p=='$') return(p); if ((r = isreg(p)) >= 0) return(regs[r]); if (equstr(p, conloc)) return(conval); return(p); } compare(op, acp1, acp2) char *acp1, *acp2; { register char *cp1, *cp2; register n1; int n2; struct { int i;}; cp1 = acp1; cp2 = acp2; if (*cp1++ != '$' || *cp2++ != '$') return(0); n1 = 0; while (*cp2 >= '0' && *cp2 <= '7') { n1 =<< 3; n1 =+ *cp2++ - '0'; } n2 = n1; n1 = 0; while (*cp1 >= '0' && *cp1 <= '7') { n1 =<< 3; n1 =+ *cp1++ - '0'; } if (*cp1=='+') cp1++; if (*cp2=='+') cp2++; do { if (*cp1++ != *cp2) return(0); } while (*cp2++); cp1 = n1; cp2 = n2; switch(op) { case JEQ: return(cp1 == cp2); case JNE: return(cp1 != cp2); case JLE: return(cp1.i <= cp2.i); case JGE: return(cp1.i >= cp2.i); case JLT: return(cp1.i < cp2.i); case JGT: return(cp1.i > cp2.i); case JLO: return(cp1 < cp2); case JHI: return(cp1 > cp2); case JLOS: return(cp1 <= cp2); case JHIS: return(cp1 >= cp2); } return(0); } setcon(ar1, ar2) char *ar1, *ar2; { register char *cl, *cv, *p; cl = ar2; cv = ar1; if (*cv != '$') return; if (!natural(cl)) return; p = conloc; while (*p++ = *cl++); p = conval; while (*p++ = *cv++); } equstr(ap1, ap2) char *ap1, *ap2; { char *p1, *p2; p1 = ap1; p2 = ap2; do { if (*p1++ != *p2) return(0); } while (*p2++); return(1); } setcc(ap) char *ap; { register char *p, *p1; p = ap; if (!natural(p)) { ccloc[0] = 0; return; } p1 = ccloc; while (*p1++ = *p++); } natural(ap) char *ap; { register char *p; p = ap; if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(') return(0); while (*p++); p--; if (*--p == '+' || *p ==')' && *--p != '5') return(0); return(1); } *cv++); } equstr(ap1, ap2) char *ap1, *ap2; { char *p1, *p2; p1 = ap1; p2 = ap2; do { if (*p1++ != *p2) return(0); } while (*p2++); return(1); } setcc(ap) char *ap; { register char *p, *p1; p = ap; if (!natural(p)) { ccloc[0] = 0; return; } p1 = ccloc; while (*p1++ = *p++); } natural(ap) char *ap; { register char *p; p = ap; if (*p=='*' || *p=='(' || *p=='-'&&*(p+1)=='(') return(0); while (*p++); p--; if dw  _  Wp WpNe % % & 5  ,_ x dp N L  @m 00 BN& & P%  5N   AmWpNefNm      D  N& & P% N  ̥   Wp17R N  ̥   )  ,  N& & P%  _00 _   N& P% * _wfw b  5 X   D:̥4˥1 . +  &&  %433  @ww *̥&  %0-  @ %2.0 dwXw T @ wD@w :B" ʥ ʋ @    ԋww D  00ww D̥ ww D Ea- % /  % e`\7aXwRw N Wp1 % 7672w.w *AWpDeC  Ԓ˥( r5 ӥ,$ww D  AmWp1CWp@*WpNe& Wp1 @e Wp1N& L ̋'̥(r5ԥ*CWp@$Wp17 @e ww @ 7ww B ̥,̋ ԥ,ww DNWpfe w @e!w rD̥r0 4 ewFw <6  ( ww D̋ wӋ̥-(̥*-(+̋ԥr̥0̥4Wp1@w _vN L 5_|N L %%  =L  ~ ӕ,7 rle07c7`  r@e07v7s ~ L A1 ww  _& @e5+̥&˥  5p3 @0tD  @LFp@w0(#̥̥̥    00 ww = :˥8 H   )  5&  %  p l  wL˥ w :AWpDe̥$  Wpe@w  & w DCԥ$ӥ$ w ˥7 te`˥0 ̥7 te`̥0̥+ ˥+ ԢӋC@ ˂ x       삱 釮 憫 ヨw "DC˥$  h Ҕww uu@ H w@ ȋw D h 7ww D̥* ̥(̥- ( 5 ԋ +̥)wPp`XX`XXXXXjjjRRRRZ %d: %s - $0$0Optimizer: out of space $0 )ii)I )) (     y( X h yy        ()   YY ))))()) I      _optab _line _first _curlp _nbrbr _nsaddr _redunm _iaftbr _njp1 _nrlab _nxjump _ncmot _nrevbr _loopiv _nredunj _nskip _ncomj _nsob _nrtst _nlit _nchange _isn _debug _lasta _lastr _firstr _revbr _regs _conloc _conval _ccloc _ophash r_rmove"L10003 L62L38L63L17pL48L55L59`L18XL16jL30RL40L57ZL54~rmovecsv fltprr1cpL2 L1L5PL20001L8@L10 _printf L11& _dualop"_findran"LL19_isreg"L4_repladd"P_dest"L21,L22$L20007L20009L20005_savereg"L20002>_setcon" _source"_setcc"D L10000L10001_singop"L50L51) L20003L53, _equstr" _redunbr"* _clearre"cret _jumpsw"~jumpswptp1njL65L20011L684L20013L702_abs"_addsob"@~addsob@pp1L73L20015JL75~absxL10004L77_equop"~equopp1p2ap1cp1cp2L79L20016L78L20018L80L81L20022L83_decref" ~decref papL866_nonlab":~nonlab:papL89NL20024DL90R_alloc"X~allocXnpanL92_sbrk L93L94/ _write _exit ~clearreiL20026~saveregpsaiasspL99L100L101L102~destfltisasL104DL105~L20028JL107|L109L20030L111L103L10008L10007L114L20032L117~singopp1p2apL119 ~dualoppp1p2apL1222L20034*L1236L121HL124D~findranLfltiasL127xL20036VL129vL126r~isregsasL132L131_check"~checkplpL134L20038L137_abort ~sourcep1p2apL140L20039L138L10010 L143*L10011"L1444L145J~repladdPL147L L148~ fltfprp1p2r1rt1L rt2~ L149vL150|L151L152L10012L146(L154L156L157L159L160L161_copy _movedat",~movedat,segdatadatpp1p2p3L162& L163L20043NL165L167dL20041ZL168hL164L169L170" L20045L10013L172 L10014 L174 ~redunbr* pp1apap1ap2L175 L176 L177H L178X _findcon" _compare" ~findcon iprL183 L20050 L182 L20047 L20049 L10037 L200 L201 L202 L203 L204 L205 L206 L207 L208 L209 ~compare acp1acp2n1n2opcp1cp2L10015* L1870 L186, L188F L200524 L189L L190f L20054T L191l L192t L196| L20055 ~setcon pclcvar1ar2L210 _natural"h L211 L213 ~equstr p1p2ap1ap2L218 L2162 L215. ~setccD pp1apL221^ L220Z L222b ~naturalh papL10038 L226 L224 L20057 L228 , L188F L200524 L189L L190f L20054T L191l L192 $ & 6 % w  5555% @&  7V? _: %@&  7 ? _   |5% % 5 %%5     @_   n     7 45 f J  n _  :  5%1%2Ne O w  ~C _D _L _P _ 7 y? _ *e _G $ 5%1J I wd _H  M _K A 5 eeee 7L y wN _ f%1# " _   # 47%[7   5%]N    _ 5_J 5:;  5- 5% 5 55  5 5? \5%*e@wNf %   5%]N 5 5 _  _  r e A! y N _, 5 _   _ _  _ 5   5 _  5  _  r e< A! y*N _ww  pj7 f wvw f eb  x 7ww  7 Ne!  f J wfwVwR. wfw>A4 Q  OfA  ^ y   F y @0fA  @9 fA @e&7w7@: w7 fw@ w fwpwlD wfBE%A E%@w ~w De  ~  % wn7 j 7 j ׯ` - X V wJ 7 L  .w@ eJ B J ӕ-   o^ xU d  w r f e0&   ԕ- k  vA W  ~e0fv  O Mz   ҋ D~C    v @ ӕ0 (f vLv Le0 9e   7wVe&  m  ~    ~ w7   0   vWp `e0eӕ?f HB:  7* & "7 7 7F@& BF 12EF*12CSjxp    !#& !$(d8Ttd$:d8JdF P \ h p  6ph@N LZf`TrxlNcvopt.tmpL%d:<0 .even cvopt.tmpcvopt.tmp=.+2; 0;.byte %o,%oL%d= L%d \0> \n> <>;.byte %o;< dfoZxfe,c:slurDbOVX(null)crt0.ocvopt.o~mainsnlflgssmodecmargctargvnlflgsmode~getct~flag>cf~putcharcopen.oputc.obadretgoodretfl|unlink.ocreat.oexit.oprintf.oformploop*rjustndigitgnum widthndfndswtabJ decimaloctalfhexZfloatsciencharac,string:longorununsignedremotelongloctblhexVprbufnulstr prstrffltpr.oN getchr.oX badret cerror.o csv.o savr5$_exit"start"_main"_peekc$ _obuf$ _sbuf$ _curbuf# _tabflg$_labno# csv" _open"_fin$_putchar"_creat"_fcreat"_getc"_printf"_fflush"n_getchar"X _putc"J_unlink"_flag">cret" cerror" _putw" _errno$pfloat"N pscien"N orununsignedremotelongloctblhexVprbufnuint peekc; int obuf[259]; int sbuf[259]; int *curbuf {&obuf[0]}; int tabflg; int labno 1; main(argc, argv) char **argv; { /* A1 -> A A2 B A O B1 C B2 D BE L BF P C1 E C2 F F G H H R I R1 J S K I M M N * +1 S +2 C +4 1 +8 z -> 4 c 10 a 14 e 20 n 63 * +0100 */ auto c,snlflg,nlflg,t,smode,m,ssmode; extern fin; smode = nlflg = snlflg = ssmode = 0; if (argc>1) if ((fin = open(argv[1], 0)) < 0) { putchar('?\n'); return; } sbuf[0] = 1; if (argc>2) if ((sbuf[0] = creat(argv[2], 0666)) < 0) { putchar('?\n'); return; } fcreat("cvopt.tmp", obuf); loop: c = getc(); if (c!='\n' && c!='\t') nlflg = 0; if (ssmode!=0 && c!='%') { ssmode = 0; curbuf = sbuf; printf("L%d:<", labno++); } switch(c) { case '\0': curbuf = obuf; printf("0\n"); fflush(obuf); curbuf = sbuf; printf(".even\n"); fin = open("cvopt.tmp", 0); while ((c = getchar()) > 0) putc(c, sbuf); fflush(sbuf); unlink("cvopt.tmp"); return; case ':': if (!smode) printf("=.+2; 0"); else putchar(':'); goto loop; case 'A': if ((c=getc())=='1' || c=='2') { putchar(c+'A'-'1'); goto loop; } putchar('O'); peekc = c; goto loop; case 'B': switch (getc()) { case '1': putchar('C'); goto loop; case '2': putchar('D'); goto loop; case 'E': putchar('L'); goto loop; case 'F': putchar('P'); goto loop; } putchar('?'); goto loop; case 'C': putchar(getc()+'E'-'1'); goto loop; case 'F': putchar('G'); goto subtre; case 'R': if ((c=getc()) == '1') putchar('J'); else { putchar('I'); peekc = c; } goto loop; case 'H': putchar('H'); goto subtre; case 'I': putchar('M'); goto loop; case 'S': putchar('K'); subtre: snlflg = 1; t = 'A'; l1: switch (c=getc()) { case '*': t++; goto l1; case 'S': t =+ 2; goto l1; case 'C': t =+ 4; goto l1; case '1': t =+ 8; goto l1; case '2': t =+ 16; goto l1; } peekc = c; putchar(t); goto loop; case '#': if(getc()=='1') putchar('#'); else putchar('"'); goto loop; case '%': if (smode) curbuf = obuf; if (ssmode==0) { if ((peekc=getc())=='[') { peekc = 0; curbuf = sbuf; while((c=getc())!=']') putchar(c); getc(); printf(";"); curbuf = obuf; goto loop; } } loop1: switch (c=getc()) { case ' ': case '\t': goto loop1; case 'a': m = 16; t = flag(); goto pf; case ',': putchar(';'); goto loop1; case 'i': m = 12; t = flag(); goto pf; case 'z': m = 4; t = flag(); goto pf; case 'r': m = 9; t = flag(); goto pf; case '1': m = 5; t = flag(); goto pf; case 'c': t = 0; m = 8; goto pf; case 'e': t = flag(); m = 20; goto pf; case 'n': t = flag(); m = 63; pf: if ((c=getc())=='*') m =+ 0100; else peekc = c; printf(".byte %o,%o", m, t); goto loop1; case '[': printf("L%d=", labno++); while ((c=getc())!=']') putchar(c); ssmode = 0; smode = 0; goto loop; case '\n': printf("\nL%d\n", labno); ssmode = 1; nlflg = 1; smode = 1; goto loop; } putchar(c); goto loop1; case '\t': if (nlflg) { nlflg = 0; goto loop; } if (smode) { tabflg++; goto loop; } putchar('\t'); goto loop; case '\n': if (!smode) { putchar('\n'); goto loop; } if (nlflg) { nlflg = 0; printf("\\0>\n"); curbuf = obuf; smode = 0; goto loop; } if (!snlflg) printf("\\n"); snlflg = 0; printf(">\n<"); nlflg = 1; goto loop; case 'X': case 'Y': case 'T': snlflg++; } putchar(c); goto loop; } getc() { register t; if (peekc) { t = peekc; peekc = 0; return(t); } return(getchar()); } flag() { register c, f; f = 0; l1: switch(c=getc()) { case 'w': f = 1; goto l1; case 'i': f = 2; goto l1; case 'b': f = 3; goto l1; case 'f': f = 4; goto l1; case 'd': f = 5; goto l1; case 's': f = 6; goto l1; case 'l': f = 8; goto l1; case 'p': f =+ 16; goto l1; } peekc = c; return(f); } putchar(c) { if (tabflg) { tabflg = 0; printf(">;.byte %o;<", c+0200); } else putc(c, curbuf); } = peekc; peekc = 0; return(t); } return(getchar()); } flag() { register c, f; f = 0; l1: switch(c=getc()) { case 'w': f = 1; goto l1; case 'i': f = 2; goto l1; case 'b': f = 3; goto l1; case 'f': f = 4; goto l1; case 'd': f = 5; goto l1; caL1:;.byte 301;<\n> <\0> L2: ;.byte 243;<(I)\n> <\0> L3:;.byte 360; <\0> L4: ;.byte 360; <\0> L5: ;.byte 360; <\0> L6:;.byte 311;<\n> <\0> L7:;.byte 311;<\n> <\0> L8:;.byte 301;<,I\n> <\0> L9:;.byte 301;<,I\n> <\0> L10: ;.byte 243;<(I),I\n> <\0> L11: ;.byte 243;<(I),I\n> <\0> L12:;.byte 301;<+,I+\n> ;.byte 301;<,I\n> <\0> L13: ;.byte 243;<+2(I),I+\n> ;.byte 243;<(I),I\n> <\0> L14:;.byte 301;<',I\n> ;.byte 301;<\n> <\0> L15:;.byte 301;<',I\n> ;.byte 302;<,A\n> <\0> L16: ;.byte 243;<(J),I\n> ;.byte 243;<(J)\n> <\0> L17: ;.byte 243;<(I),-(sp)\n> ;.byte 243;<(I)\n> ;.byte 250; <\0> L18: ;.byte 243;<(J),I\n> ;.byte 302;<,#(J)\n> <\0> L19: ;.byte 243;<(I),-(sp)\n> ;.byte 302;<,#(I)\n> ;.byte 250; <\0> L20: ;.byte 244;<1,A+\n> ;.byte 301;<\n> <\0> L21: ;.byte 243;<+2(J),I+\n> ;.byte 243;<(J),I\n> ;.byte 244;<1,#+2(J)\n> ;.byte 243;<(J)\n> <\0> L22: ;.byte 243;<+2(I),-(sp)\n> ;.byte 243;<(I),-(sp)\n> ;.byte 244;<1,#+2(I)\n> ;.byte 243;<(I)\n> ;.byte 250; ;.byte 250; <\0> L23: ;.byte 311;<\n> <\0> L24: ;.byte 311;<\n> ;.byte 311;<+\n> ;.byte 311;<\n> <\0> L25: ;.byte 311;<,A\n> <\0> L26: ;.byte 311;<,A\n> <\0> L27: ;.byte 311;<,#(I)\n> <\0> L28: <movC>;.byte 302;<,#(I)\n> ;.byte 243;<(I),I\n> <\0> L29: ;.byte 311;<,#(I)\n> <\0> L30: ;.byte 312;<,#(I)\n> ;.byte 312;<,I\n> <\0> L31: ;.byte 311;<,#(J)\n> <\0> L32: ;.byte 311;<,#(J)\n> <\0> L33: ;.byte 311;<,*(sp)+\n> <\0> L34: ;.byte 311;<,*(sp)+\n> <\0> L35: ;.byte 311;<+,A+\n> ;.byte 311;<,A\n> <\0> L36: ;.byte 311;<+,2+#(J)\n> ;.byte 311;<,#(J)\n> <\0> L37: ;.byte 311;<,*(sp)\n> ;.byte 244;<2,(sp)\n> ;.byte 311;<+,*(sp)+\n> <\0> L38: ;.byte 332;<,A'\n> ;.byte 311;<,A\n> <\0> L40: ;.byte 332;<,#(I)\n> ;.byte 250; ;.byte 250; <\0> L41: <\0> L42: ;.byte 311;<\n> <\0> add1:;L43: ;.byte 302;<,I\n> <\0> add2:;L44: ;.byte 242;<(J),I\n> <\0> add3:;L45: ;.byte 312;<,I\n> <\0> add4:;L46: ;.byte 252;<(sp)+,I\n> <\0> add5:;L47: <GA> ;.byte 250; <\0> L48: ;.byte 302;<,I+\n> ;.byte 311;<\n> <\0> L49: ;.byte 302;<,I\n> ;.byte 302;<+,I+\n> ;.byte 311;<\n> <\0> addl1:;L50: ;.byte 312;<+,I+\n> ;.byte 311;<\n> ;.byte 312;<,I\n> <\0> addl2:;L51: ;.byte 250; ;.byte 250; ;.byte 311;<\n> <\0> L53: ;.byte 311;<,(sp)\n> ;.byte 250; <\0> L55: ;.byte 311;<,(sp)\n> ;.byte 250; ;.byte 311;<+,(sp)\n> ;.byte 250; <\0> L56: ;.byte 311;<\n> <\0> L61:

;.byte 302;<,I-\n> <\0> L62:
;.byte 242;<(J),I-\n> <\0> L63:
;.byte 312;<,I-\n> <\0> L64:
;.byte 250; <\0> addq1:;L69:;.byte 302;<,A'\n> ;.byte 301;<,I\n> <\0> addq1a:;L70:;.byte 301;<',I\n> ;.byte 302;<,I\n> ;.byte 311;<,A\n> <\0> addq2:;L71: ;.byte 242;<(I),A'\n> ;.byte 301;<,I\n> <\0> addq3:;L72: ;.byte 311;<,A'\n> ;.byte 301;<,I\n> <\0> addq4:;L73: ;.byte 242;<(I),#(J)\n> ;.byte 243;<(J),I\n> <\0> addq4a:;L74:;.byte 301;<',I\n> ;.byte 312;<,I\n> ;.byte 311;<,A\n> <\0> addq5:;L75: ;.byte 301;<',I\n> ;.byte 250; ;.byte 311;<,A\n> <\0> addq6:;L76: ;.byte 301;<',I\n> ;.byte 250; ;.byte 311;<,A\n> <\0> addq7:;L77: ;.byte 311;<,#(J)\n> ;.byte 243;<(J),I\n> <\0> addq8:;L78: ;.byte 250; ;.byte 243;<(I),I\n> <\0> addq9:;L79: ;.byte 252;<2(sp),I\n> ;.byte 250; ;.byte 311;<,*(sp)+\n> <\0> addq9a:;L80: ;.byte 243;<(I),I\n> ;.byte 250; ;.byte 311;<,#(I)\n> <\0> addq10:;L81: ;.byte 243;<(I),J\n> ;.byte 250; ;.byte 312;<,#(I)\n> ;.byte 312;<,I\n> <\0> L89:;.byte 301;<',I\n> ;.byte 311;<-\n> ;.byte 302;<,I-\n> ;.byte 311;<-,A\n> <\0> L90: ;.byte 301;<',I\n> ;.byte 311;<-\n>
;.byte 250; ;.byte 311;<-,A\n> <\0> L91: ;.byte 243;<(J),I\n> ;.byte 311;<-\n>
;.byte 250; ;.byte 311;<-,#(J)\n> <\0> L92: ;.byte 252;<2(sp),I\n> ;.byte 311;<-\n>
;.byte 250; ;.byte 311;<-,*(sp)+\n> <\0> L99:;.byte 301;<',I\n> ;.byte 311;<-\n>
;.byte 302;<,I-\n> ;.byte 311;<,A\n> <\0> L100: ;.byte 301;<',I\n> ;.byte 311;<-\n>
;.byte 250; ;.byte 311;<,A\n> <\0> L101: ;.byte 243;<(J),I\n> ;.byte 311;<-\n>
;.byte 250; ;.byte 311;<,#(J)\n> <\0> L102: ;.byte 252;<2(sp),I\n> ;.byte 311;<-\n>
;.byte 250; ;.byte 311;<,*(sp)+\n> <\0> L104: ;.byte 301;<',I\n> ;.byte 311;<,(sp)\n> ;.byte 250; ;.byte 311;<,A\n> <\0> L105: ;.byte 252;<(sp),-(sp)\n> ;.byte 311;<,(sp)\n> ;.byte 250; ;.byte 311;<,*(sp)+\n> <\0> L106:;.byte 301;<'\n> ;.byte 301;<,I\n> <\0> L107: ;.byte 243;<(I)\n> ;.byte 243;<(I),I\n> <\0> L113:;.byte 301;<,I\n> <\0> L114: ;.byte 243;<(I),I\n> <\0> L115: ;.byte 311;<,I\n> <\0> L116: ;.byte 311;<,I\n> <\0> L117: ;.byte 311;<,-(sp)\n> ;.byte 250; ;.byte 250; <\0> L118: ;.byte 301;<,I\n> <\0> L119: <setl\n> ;.byte 243;<(I),I\n> <\0> L120: ;.byte 250; <\0> L121: ;.byte 311;<\n> <\0> L122:;.byte 301;<+,I\n> <\0> L123: ;.byte 243;<+2(I),I\n> <\0> L124: ;.byte 311;<+,I\n> <\0> L125: ;.byte 360; ;.byte 244;<10,sp\n> <\0> L126: ;.byte 360; ;.byte 244;<6,sp\n> <\0> move1:;L127:;.byte 301;<\n> <\0> move2:;L128: ;.byte 243;<(I)\n> <\0> move3:;L129:;.byte 302;<,A\n> <\0> move4:;L130: ;.byte 242;<(I),A\n> <\0> move5:;L131: ;.byte 311;<,A\n> <\0> move6:;L132: ;.byte 302;<,#(I)\n> <\0> move7:;L133: ;.byte 242;<(J),#(I)\n> <\0> move8:;L134: ;.byte 312;<,#(I)\n> <\0> move9:;L135: ;.byte 242;<(I),#(J)\n> <\0> move10:;L136: ;.byte 311;<,#(J)\n> <\0> move11:;L137: ;.byte 242;<(I),*(sp)+\n> <\0> move12:;L138: ;.byte 311;<,*(sp)+\n> <\0> L139: ;.byte 311;<,A\n> <\0> L140: ;.byte 311;<,#(J)\n> <\0> L141:;.byte 301;<\n> ;.byte 301;<+\n> <\0> L142: ;.byte 243;<(I)\n> ;.byte 262;<+#(I)\n> <\0> move13a:;L143:;.byte 302;<,A+\n> ;.byte 301;<\n> <\0> L144:;.byte 302;<,A+\n> ;.byte 301;<\n> <\0> L145: ;.byte 242;<(I),A+\n> ;.byte 301;<\n> <\0> L146: ;.byte 311;<,A+\n> ;.byte 301;<\n> <\0> L147: ;.byte 311;<,A\n> <\0> L148: ;.byte 311;<,#(J)\n> <\0> move13:;L149:;.byte 302;<,A\n> ;.byte 302;<+,A+\n> ;.byte 301;<\n> <\0> move14:;L150: ;.byte 242;<(I),A\n> ;.byte 242;<+2(I),A+\n> ;.byte 301;<\n> <\0> move14a:;L151: ;.byte 302;<,2+#(I)\n> ;.byte 243;<(I)\n> <\0> move15:;L152: ;.byte 311;<,A\n> ;.byte 311;<+,A+\n> ;.byte 301;<\n> <\0> L153: ;.byte 302;<,#+2(I)\n> ;.byte 243;<(I)\n> <\0> move16:;L154: ;.byte 311;<+,#+2(J)\n> ;.byte 243;<(J)\n> ;.byte 311;<,#(J)\n> <\0> L155: ;.byte 250; ;.byte 243;<(I)\n> <\0> move17:;L156: ;.byte 250; ;.byte 250; ;.byte 243;<(I)\n> <\0> L175: ;.byte 311;<,*(sp)\n> ;.byte 250; ;.byte 311;<+,2(I)\n> <\0> L176:<\0> L177:;.byte 301;<\n> <\0> L183: ;.byte 301;<',J\n> ;.byte 242;<(I),J\n> ;.byte 312;<,A\n> <\0> L184: ;.byte 301;<',J\n> ;.byte 311;<,J\n> ;.byte 312;<,A\n> <\0> L187: ;.byte 243;<(I),J\n> ;.byte 250; ;.byte 312;<,#(I)\n> <\0> L195:;.byte 301;<\n> <\0> L196: ;.byte 243;<(I)\n> <\0> L197:;.byte 301;<\n> <\0> L198: ;.byte 243;<(I)\n> <\0> L199:;.byte 302;<,A\n> <\0> L200: ;.byte 242;<(I),A\n> <\0> L201: ;.byte 311;<,A\n> <\0> L202: ;.byte 302;<,I\n> ;.byte 311;<,A\n> ;.byte 311;<+,A+\n> <\0> L203: ;.byte 250; ;.byte 311;<,A\n> ;.byte 311;<+,A+\n> <\0> L204: ;.byte 262;<(sp),I\n> ;.byte 262;<(I),I+\n> ;.byte 250; ;.byte 250; ;.byte 311;<,*(sp)\n> ;.byte 244;<2,(sp)\n> ;.byte 311;<+,*(sp)+\n> <\0> L205:;.byte 332;<,A'\n> ;.byte 302;<,A\n> <\0> L206: ;.byte 332;<,A'\n> ;.byte 311;<,A\n> <\0> L207: ;.byte 332;<,#(I)\n> ;.byte 302;<,#(I)\n> <\0> fas1:;L208: ;.byte 332;<,#(J)\n> ;.byte 311;<,#(J)\n> <\0> L209: ;.byte 332;<,#(I)\n> ;.byte 312;<,#(I)\n> <\0> L210: ;.byte 332;<,#(I)\n> ;.byte 250; <\0> L212:;.byte 301;<,I\n> <\0> L214: ;.byte 243;<(I),I\n> <\0> L215: <\0> L226:;.byte 301;<\n> ;.byte 301;<+\n> <\0> L227:;.byte 301;<\n> ;.byte 301;<+,B\n> <\0> lcmp1:;L228:;.byte 301;<,B\n> ;.byte 301;<+,B+\n> <\0> L229: ;.byte 243;<(I)\n> ;.byte 243;<+2(I)\n> <\0> L230: ;.byte 243;<(I)\n> ;.byte 243;<+2(I),B\n> <\0> lcmp2:;L231: ;.byte 243;<(I),B\n> ;.byte 243;<+2(I),B+\n> <\0> L232: ;.byte 311;<\n> ;.byte 311;<+\n> <\0> L233: ;.byte 311;<\n> ;.byte 311;<+,B\n> <\0> lcmp3:;L234: ;.byte 311;<,B\n> ;.byte 311;<+,B+\n> <\0> lcmp4:;L235: ;.byte 243;<(I),"(J)\n> ;.byte 243;<+2(I),"+2(J)\n> <\0> lcmp5:;L236: ;.byte 311;<,"(J)\n> ;.byte 311;<+,"+2(J)\n> <\0> L242:;.byte 244;<0,A\n> ;.byte 302;<,A+\n> <\0> L243: ;.byte 244;<0,"(I)\n> ;.byte 302;<,"+2(I)\n> <\0> L249: ;.byte 244;<0,I\n> ;.byte 302;<,I+\n> <\0> L250: <\0> L251:;.byte 255;<(sp)\n> <\0> L252:;.byte 301;<,-(sp)\n> <\0> L253: ;.byte 243;<(I),-(sp)\n> <\0> L254:;.byte 301;<+,-(sp)\n> ;.byte 301;<,-(sp)\n> <\0> L255: ;.byte 250; <\0> L256: ;.byte 302;<,(sp)\n> <\0> L257: ;.byte 242;<(I),(sp)\n> <\0> L258: ;.byte 311;<,(sp)\n> <\0> L259: ;.byte 255;<(sp)\n> <\0> L260: ;.byte 311;<,-(sp)\n> <\0> .even / / c code tables-- compile to register / .globl _regtab .data _regtab=. 106.; cr106 30.; cr70 31.; cr70 32.; cr32 33.; cr32 37.; cr37 38.; cr37 98.; cr100 99.; cr100 80.; cr80 40.; cr40 41.; cr40 / - like + 42.; cr42 43.; cr43 14.; cr43 44.; cr43 45.; cr45 46.; cr40 55.; cr40 48.; cr40 49.; cr49 70.; cr70 71.; cr70 72.; cr72 73.; cr73 74.; cr74 75.; cr75 76.; cr72 78.; cr70 85.; cr70 79.; cr79 102.; cr102 51.; cr51 52.; cr52 56.; cr56 57.; cr57 58.; cr58 59.; cr59 91.; cr91 82.; cr82 83.; cr82 84.; cr82 86.; cr86 87.; cr86 88.; cr86 16.; cr16 92.; cr92 0 .text / goto cr102=.+2; 0 .byte 20,0;.byte 77,0 L1 .byte 177,0;.byte 77,0 L2 / call cr100=.+2; 0 .byte 20,0;.byte 77,0 L3 .byte 177,0;.byte 77,0 L4 .byte 77,0;.byte 77,0 L5 / addressible cr106=.+2; 0 .byte 4,0;.byte 77,0 L6 .byte 4,4;.byte 77,0 L7 .byte 20,0;.byte 77,0 L8 .byte 20,5;.byte 77,0 L8 .byte 20,4;.byte 77,0 L9 .byte 177,0;.byte 77,0 L10 .byte 177,5;.byte 77,0 L10 .byte 177,4;.byte 77,0 L11 .byte 20,10;.byte 77,0 L12 .byte 177,10;.byte 77,0 L13 / ++,-- postfix cr32=.+2; 0 .byte 20,0;.byte 5,0 L14 .byte 20,1;.byte 77,0 L15 .byte 124,0;.byte 5,0 L16 .byte 177,0;.byte 5,0 L17 .byte 124,1;.byte 77,0 L18 .byte 177,1;.byte 77,0 L19 .byte 20,10;.byte 5,0 L20 .byte 124,10;.byte 5,0 L21 .byte 177,10;.byte 5,0 L22 / - unary, ~ cr37=.+2; 0 .byte 77,0;.byte 77,0 L23 .byte 77,4;.byte 77,0 L23 .byte 77,10;.byte 77,0 L24 / = cr80=.+2; 0 .byte 20,0;.byte 77,0 L25 .byte 20,5;.byte 77,4 L25 .byte 20,4;.byte 77,4 L26 .byte 177,5;.byte 20,4 L27 .byte 177,0;.byte 20,1 L28 .byte 177,4;.byte 20,4 L29 .byte 177,0;.byte 24,0 L30 .byte 124,5;.byte 77,4 L31 .byte 124,4;.byte 77,4 L32 .byte 177,0;.byte 77,0 L33 .byte 177,5;.byte 77,4 L33 .byte 177,4;.byte 77,4 L34 .byte 20,10;.byte 77,10 L35 .byte 124,10;.byte 77,10 L36 .byte 177,10;.byte 77,10 L37 / field assign, value in reg. cr16=.+2; 0 .byte 20,0;.byte 77,0 L38 .byte 124,0;.byte 77,0 L39 L39=fas1 .byte 177,0;.byte 77,0 L40 / +, -, |, &~, << cr40=.+2; 0 .byte 77,0;.byte 4,0 L41 .byte 77,0;.byte 5,0 L42 .byte 77,0;.byte 20,1 L43 .byte 77,4;.byte 20,5 L43 .byte 77,0;.byte 124,1 L44 .byte 77,4;.byte 124,5 L44 .byte 77,0;.byte 24,0 L45 .byte 77,4;.byte 24,4 L45 .byte 77,0;.byte 177,1 L46 .byte 77,4;.byte 177,5 L46 .byte 77,0;.byte 77,0 L47 .byte 77,4;.byte 77,4 L47 .byte 77,10;.byte 10,0 L48 .byte 77,10;.byte 20,10 L49 .byte 77,10;.byte 24,10 L50 .byte 77,10;.byte 77,10 L51 / ^ -- xor cr49=.+2; 0 .byte 77,0;.byte 24,0 L52 L52=add3 .byte 77,0;.byte 77,0 L53 .byte 77,10;.byte 24,10 L54 L54=addl1 .byte 77,10;.byte 77,10 L55 / >> (all complicated cases taken care of by << -) cr45=.+2; 0 .byte 77,0;.byte 5,0 L56 / * -- I must be odd on integers cr42=.+2; 0 .byte 77,0;.byte 20,1 L57 .byte 77,4;.byte 20,5 L57 L57=add1 .byte 77,0;.byte 124,1 L58 .byte 77,4;.byte 124,5 L58 L58=add2 .byte 77,0;.byte 24,0 L59 .byte 77,4;.byte 24,4 L59 L59=add3 .byte 77,0;.byte 77,0 L60 .byte 77,4;.byte 77,4 L60 L60=add5 / / I must be odd on integers cr43=.+2; 0 .byte 77,0;.byte 20,1 L61 .byte 77,0;.byte 124,1 L62 .byte 77,0;.byte 24,0 L63 .byte 77,0;.byte 77,0 L64 .byte 77,4;.byte 20,5 L65 L65=add1 .byte 77,4;.byte 124,5 L66 L66=add2 .byte 77,4;.byte 24,4 L67 L67=add3 .byte 77,4;.byte 77,4 L68 L68=add5 / =+, =-, =|, =&~ cr70=.+2; 0 .byte 20,1;.byte 20,1 L69 .byte 20,0;.byte 20,1 L70 .byte 20,5;.byte 20,5 L70 .byte 20,1;.byte 177,1 L71 .byte 20,1;.byte 77,0 L72 .byte 124,1;.byte 177,1 L73 .byte 20,5;.byte 24,4 L74 .byte 20,0;.byte 77,0 L75 .byte 20,5;.byte 77,4 L75 .byte 20,4;.byte 77,4 L76 .byte 124,1;.byte 77,0 L77 .byte 177,1;.byte 77,0 L78 .byte 177,0;.byte 77,0 L79 .byte 177,5;.byte 77,4 L80 .byte 177,4;.byte 77,4 L81 / =*, =<< (for integer multiply, I must be odd) cr72=.+2; 0 .byte 20,0;.byte 20,1 L82 .byte 20,5;.byte 20,5 L82 L82=addq1a .byte 20,4;.byte 77,4 L83 L83=addq6 .byte 20,5;.byte 24,4 L84 L84=addq4a .byte 20,0;.byte 77,0 L85 .byte 20,5;.byte 77,4 L85 L85=addq5 .byte 177,0;.byte 77,0 L86 L86=addq9 .byte 177,5;.byte 77,4 L87 L87=addq9a .byte 177,4;.byte 77,4 L88 L88=addq10 / =/ ; I must be odd on integers cr73=.+2; 0 .byte 20,0;.byte 20,1 L89 .byte 20,0;.byte 77,0 L90 .byte 124,0;.byte 77,0 L91 .byte 177,0;.byte 77,0 L92 .byte 20,5;.byte 20,5 L93 L93=addq1a .byte 20,5;.byte 24,4 L94 L94=addq4a .byte 20,5;.byte 77,4 L95 L95=addq5 .byte 20,4;.byte 77,4 L96 L96=addq6 .byte 177,5;.byte 77,4 L97 L97=addq9a .byte 177,4;.byte 77,4 L98 L98=addq10 / =mod; I must be odd on integers cr74=.+2; 0 .byte 20,0;.byte 20,1 L99 .byte 20,0;.byte 77,0 L100 .byte 124,0;.byte 77,0 L101 .byte 177,0;.byte 77,0 L102 / =^ -- =xor cr79=.+2; 0 .byte 20,1;.byte 77,0 L103 L103=addq3 .byte 20,3;.byte 77,0 L104 .byte 177,0;.byte 77,0 L105 / =>> (all complicated cases done by =<< -) cr75=.+2; 0 .byte 20,0;.byte 5,0 L106 .byte 177,0;.byte 5,0 L107 / << for longs cr91=.+2; 0 .byte 77,10;.byte 20,1 L108 L108=add1 .byte 77,10;.byte 124,1 L109 L109=add2 .byte 77,10;.byte 24,0 L110 L110=add3 .byte 77,10;.byte 177,1 L111 L111=add4 .byte 77,10;.byte 77,0 L112 L112=add5 / int -> float cr51=.+2; 0 .byte 20,1;.byte 77,0 L113 .byte 177,1;.byte 77,0 L114 .byte 77,0;.byte 77,0 L115 / float, double -> int cr52=.+2; 0 .byte 77,4;.byte 77,0 L116 / double (float) to long cr56=.+2; 0 .byte 77,4;.byte 77,0 L117 / long to double cr57=.+2; 0 .byte 20,10;.byte 77,0 L118 .byte 177,10;.byte 77,0 L119 .byte 77,10;.byte 77,0 L120 / integer to long cr58=.+2; 0 .byte 77,0;.byte 77,0 L121 / long to integer cr59=.+2; 0 .byte 20,10;.byte 77,0 L122 .byte 177,10;.byte 77,0 L123 .byte 77,10;.byte 77,0 L124 / *, /, remainder for longs. cr82=.+2; 0 .byte 77,10;.byte 77,10 L125 / =*, =/, =rem for longs / Operands of the form &x op y, so stack space is known. cr86=.+2; 0 .byte 77,0;.byte 77,10 L126 / / c code tables -- compile for side effects. / Olso set condition codes properly (except for ++, --) / .globl _efftab .data _efftab=. 30.; ci70 31.; ci70 32.; ci70 33.; ci70 80.; ci80 70.; ci70 71.; ci70 / - like + 78.; ci78 79.; ci79 85.; ci78 75.; ci75 76.; ci76 16.; ci16 0 .text / = ci80=.+2; 0 .byte 20,0;.byte 4,0 L127 .byte 20,5;.byte 4,4 L127 .byte 177,0;.byte 4,0 L128 .byte 177,5;.byte 4,4 L128 .byte 20,0;.byte 20,1 L129 .byte 20,3;.byte 20,0 L129 .byte 20,3;.byte 177,0 L130 .byte 20,0;.byte 177,1 L130 .byte 20,0;.byte 77,0 L131 .byte 177,0;.byte 20,1 L132 .byte 177,3;.byte 20,0 L132 .byte 177,0;.byte 124,1 L133 .byte 177,3;.byte 124,0 L133 .byte 177,0;.byte 24,0 L134 .byte 124,0;.byte 177,1 L135 .byte 124,3;.byte 177,0 L135 .byte 124,0;.byte 77,0 L136 .byte 177,0;.byte 177,1 L137 .byte 177,3;.byte 177,0 L137 .byte 177,0;.byte 77,0 L138 .byte 20,1;.byte 77,4 L139 .byte 124,1;.byte 77,4 L140 .byte 20,10;.byte 4,0 L141 .byte 177,10;.byte 4,0 L142 .byte 20,10;.byte 10,0 L143 .byte 20,10;.byte 20,1 L144 .byte 20,10;.byte 177,1 L145 .byte 20,10;.byte 77,0 L146 .byte 20,10;.byte 77,4 L147 .byte 124,10;.byte 77,4 L148 .byte 20,10;.byte 20,10 L149 .byte 20,10;.byte 177,10 L150 .byte 177,10;.byte 10,0 L151 .byte 20,10;.byte 77,10 L152 .byte 177,10;.byte 20,1 L153 .byte 124,10;.byte 77,10 L154 .byte 177,10;.byte 77,0 L155 .byte 177,10;.byte 77,10 L156 / =| and =& ~ ci78=.+2; 0 .byte 20,0;.byte 20,0 L157 L157=move3 .byte 20,0;.byte 77,0 L158 L158=move5 .byte 177,0;.byte 20,0 L159 L159=move6 .byte 177,0;.byte 124,0 L160 L160=move7 .byte 177,0;.byte 24,0 L161 L161=move8 .byte 124,0;.byte 177,0 L162 L162=move9 .byte 124,0;.byte 77,0 L163 L163=move10 .byte 177,0;.byte 177,0 L164 L164=move11 .byte 177,0;.byte 77,0 L165 L165=move12 .byte 20,10;.byte 10,0 L166 L166=move13a .byte 20,10;.byte 20,10 L167 L167=move13 .byte 20,10;.byte 177,10 L168 L168=move14 .byte 20,10;.byte 77,10 L169 L169=move15 .byte 177,10;.byte 10,0 L170 L170=move14a .byte 124,10;.byte 77,10 L171 L171=move16 .byte 177,10;.byte 77,10 L172 L172=move17 / =^ ci79=.+2; 0 .byte 20,10;.byte 77,10 L173 L173=move15 .byte 124,10;.byte 77,10 L174 L174=move16 .byte 177,10;.byte 77,10 L175 / =+ ci70=.+2; 0 .byte 177,0;.byte 4,0 L176 .byte 20,0;.byte 4,0 L176 .byte 20,0;.byte 5,0 L177 .byte 20,1;.byte 20,1 L178 L178=move3 .byte 20,1;.byte 177,1 L179 L179=move4 .byte 20,1;.byte 77,0 L180 L180=move5 .byte 177,0;.byte 5,0 L181 L181=move2 .byte 124,1;.byte 177,1 L182 L182=move9 .byte 20,0;.byte 177,1 L183 .byte 20,0;.byte 77,0 L184 .byte 124,1;.byte 77,0 L185 L185=move10 .byte 177,1;.byte 77,0 L186 L186=move12 .byte 177,0;.byte 77,0 L187 .byte 20,10;.byte 10,0 L188 L188=move13a .byte 20,10;.byte 20,10 L189 L189=move13 .byte 20,10;.byte 177,10 L190 L190=move14 .byte 20,10;.byte 77,10 L191 L191=move15 .byte 177,10;.byte 10,0 L192 L192=move14a .byte 124,10;.byte 77,10 L193 L193=move16 .byte 177,10;.byte 77,10 L194 L194=move17 / =>> (all harder cases handled by =<< -) ci75=.+2; 0 .byte 20,0;.byte 5,0 L195 .byte 177,0;.byte 5,0 L196 / =<< ci76=.+2; 0 .byte 20,0;.byte 5,0 L197 .byte 177,0;.byte 5,0 L198 .byte 11,0;.byte 20,1 L199 .byte 11,0;.byte 177,1 L200 .byte 11,0;.byte 77,0 L201 / =<< for longs cr92=.+2; 0 .byte 20,10;.byte 20,1 L202 .byte 20,10;.byte 77,0 L203 .byte 177,10;.byte 77,0 L204 / field = ... ci16=.+2; 0 .byte 20,0;.byte 20,0 L205 .byte 20,0;.byte 77,0 L206 .byte 177,0;.byte 20,0 L207 .byte 124,0;.byte 77,0 L208 .byte 177,0;.byte 24,0 L209 .byte 177,0;.byte 77,0 L210 / / c code tables-- set condition codes / .globl _cctab .data _cctab=. 106.; cc60 28.; rest 55.; rest 34.; rest 35.; rest 36.; rest 37.; rest 40.; rest 41.; rest 42.; rest 43.; rest 45.; rest 46.; rest 81.; cc81 / & as in "if ((a&b)==0)" 48.; rest 60.; cc60 61.; cc60 62.; cc60 63.; cc60 64.; cc60 65.; cc60 66.; cc60 67.; cc60 68.; cc60 69.; cc60 72.; rest 73.; rest 79.; rest 0 .text / relationals cc60=.+2; 0 .byte 20,0;.byte 4,0 L211 .byte 20,5;.byte 4,4 L211 L211=move1 .byte 20,4;.byte 4,0 L212 .byte 177,0;.byte 4,0 L213 .byte 177,5;.byte 4,4 L213 L213=move2 .byte 177,4;.byte 4,0 L214 .byte 77,0;.byte 4,0 L215 .byte 77,4;.byte 4,4 L215 .byte 20,1;.byte 20,1 L216 .byte 20,3;.byte 20,3 L216 L216=move3 .byte 177,1;.byte 20,1 L217 .byte 177,3;.byte 20,3 L217 L217=move6 .byte 77,0;.byte 20,1 L218 .byte 77,4;.byte 20,5 L218 L218=add1 .byte 177,1;.byte 124,1 L219 .byte 177,3;.byte 124,3 L219 L219=move7 .byte 177,1;.byte 24,0 L220 L220=move8 .byte 77,0;.byte 124,1 L221 .byte 77,4;.byte 124,5 L221 L221=add2 .byte 77,0;.byte 24,0 L222 .byte 77,4;.byte 24,4 L222 L222=add3 .byte 177,1;.byte 177,1 L223 .byte 177,3;.byte 177,3 L223 L223=move11 .byte 177,1;.byte 77,0 L224 L224=move12 .byte 77,0;.byte 77,0 L225 .byte 77,4;.byte 77,4 L225 L225=add5 .byte 20,10;.byte 4,0 L226 .byte 20,10;.byte 10,0 L227 .byte 20,10;.byte 20,10 L228 .byte 177,10;.byte 4,0 L229 .byte 177,10;.byte 10,0 L230 .byte 177,10;.byte 20,10 L231 .byte 77,10;.byte 4,0 L232 .byte 77,10;.byte 10,0 L233 .byte 77,10;.byte 20,10 L234 .byte 177,10;.byte 124,10 L235 .byte 77,10;.byte 124,10 L236 / & as in "if ((a&b) ==0)" cc81=.+2; 0 .byte 20,0;.byte 20,0 L237 L237=move3 .byte 177,0;.byte 20,0 L238 L238=move6 .byte 77,0;.byte 20,0 L239 L239=add1 .byte 77,0;.byte 24,0 L240 L240=add3 .byte 77,0;.byte 77,0 L241 L241=add5 .byte 20,10;.byte 10,0 L242 .byte 177,10;.byte 10,0 L243 .byte 20,10;.byte 20,10 L244 L244=lcmp1 .byte 177,10;.byte 20,10 L245 L245=lcmp2 .byte 77,10;.byte 20,10 L246 L246=lcmp3 .byte 177,10;.byte 124,10 L247 L247=lcmp4 .byte 77,10;.byte 124,10 L248 L248=lcmp5 .byte 77,10;.byte 10,0 L249 / set codes right rest=.+2; 0 .byte 77,0;.byte 77,0 L250 .byte 77,4;.byte 77,4 L250 / / c code tables-- expression to -(sp) / .globl _sptab .data _sptab=. 106.; cs106 40.; cs40 41.; cs40 55.; cs40 48.; cs40 58.; cs58 56.; cs56 0 .text / name cs106=.+2; 0 .byte 4,0;.byte 77,0 L251 .byte 4,4;.byte 77,0 L251 .byte 20,1;.byte 77,0 L252 .byte 177,1;.byte 77,0 L253 .byte 20,10;.byte 77,0 L254 / +, -, |, &~ cs40=.+2; 0 .byte 77,0;.byte 5,0 L255 .byte 77,0;.byte 20,1 L256 .byte 77,0;.byte 177,1 L257 .byte 77,0;.byte 77,0 L258 / integer to long cs58=.+2; 0 .byte 77,0;.byte 77,0 L259 / float to long cs56=.+2; 0 .byte 77,4;.byte 77,0 L260 0 tab .data _sptab=. 106.; cs106 40.; cs40 41.; cs40 55.; cs40 48.; cs40 58.; cs58 56.; cs56 0 .text / name cs106=.+2; 0 .byte 4,0;.byte 77,0 L251 .byte 4,4;.byte 77,0 L251 .byte 20,1;.byte 77,0 L252 .byte 177,1;.byte 77,0 L253 .byte 20,10;.byte 77,0 L254 / +, -, |, &~ cs40=.+2; 0 .byte 77,0;.byte 5,0 L255 .byte 77,0;.byte 20,1 L256 .byte 77,0;.byte 177,1 L257 .byte 77,0;.byte 77,0 L258 / integer to long cs58=.+2; 0 .byte 77,0;.byte 77,0 L259 / floattjmp GBjmp(I) jsrc,MA GBjsrc,#(I) GAjsrc,(I) clr clrf movC,I movof,I GBmovC(I),I GBmovof(I),I mov+,I+ mov,I GBmov+2(I),I+ mov(I),I movC',I M'C mov',I M,A GJmovC(J),I M'C(J) GBmovC(I),-(sp) M'C(I) movCsp)+,I GJmov(J),I M,#(J) GBmov(I),-(sp) M,#(I) movsp)+,I GAM1,A+ V GJmov+2(J),I+ mov(J),I M1,#+2(J) V(J) GBmov+2(I),-(sp) mov(I),-(sp) add1,#+2(I) V(I) movsp)+,I movsp)+,I+ GAMP GAM M+ V KAmovC,A KAmovfo,A GBKAmovf,#(I) GBmovC,#(I) movC(I),I GBKAmovfo,#(I) GBKImovC,#(I) movC,I KAGJmovf,#(J) KAGJmovfo,#(J) GDKAmovC,*(sp)+ GDKAmovfo,*(sp)+ KAmov+,A+ mov,A KAGJmov+,2+#(J) mov,#(J) GDKAmov,*(sp) add2,(sp) mov+,*(sp)+ KAbicC,A' bisC,A KCGBbicC,#(I) bisCsp),#(I) movsp)+,I GAGAM' GAMD,I GAKJMD(J),I GAKIMP,I KDGAMD(sp)+,I KCGAMPsp)+,I GAM,I+ V GAM,I M+,I+ V GAKIM+,I+ V M,I KCGAMsp)+,I Msp)+,I+ V GCKAxor,(sp) movsp)+,I KCGAM,(sp) movsp)+,I M+,(sp) movsp)+,I+ GAasr GATdiv,I- GATKJdiv(J),I- GATKIdiv,I- KCGATdivsp)+,I- M,A' mov,I movC',I MP,I movC,A KBM(I),A' mov,I KAM,A' mov,I KBGJM(I),#(J) mov(J),I movf',I KIMP,I movf,A KCmovC',I MPsp)+,I movC,A KCmovof',I MPsp)+,I movfo,A KAGJM,#(J) mov(J),I KCGBMsp)+,#(I) mov(I),I GDKCmovC2(sp),I MPsp)+,I movC,*(sp)+ KCGBmovC(I),I MPsp)+,I movC,#(I) KCGBmovof(I),J MPsp)+,J movfo,#(I) movf,I movC',I sxt- divP,I- movC-,A KCmovC',I sxt- divsp)+,I- movC-,A KCGJmovC(J),I sxt- divsp)+,I- movC-,#(J) GDKCmovC2(sp),I sxt- divsp)+,I- movC-,*(sp)+ movC',I sxt- div,I- movC,A KCmovC',I sxt- divsp)+,I- movC,A KCGJmovC(J),I sxt- divsp)+,I- movC,#(J) GDKCmovC2(sp),I sxt- divsp)+,I- mov,*(sp)+ KCmovb',I xor,(sp) movsp)+,I movb,A GDmovC(sp),-(sp) KAxor,(sp) movCsp)+,I movC,*(sp)+ asrC' movC,I GBasrC(I) movC(I),I movif,I GBmovif(I),I GAmovif,I GAmovfi,I GAsetl movfi,-(sp) movsp)+,I movsp)+,I+ seti setl movif,I seti GBsetl movif(I),I seti GCsetl movifsp)+,I seti GI!sxt mov+,I GBmov+2(I),I GAmov+,I KCGCjsrc,M add10,sp KCGCjsrc,M add6,sp M'C GBM'C(I) ML,A KBML(I),A KAMC,A GBML,#(I) GBKJML(J),#(I) GBKIMC,#(I) KBGJML(I),#(J) KAGJMC,#(J) GDKBML(I),*(sp)+ GDKAMC,*(sp)+ KAmovfi,A KAGJmovfi,#(J) clr clr+ GBclr(I) clr+#(I) M,A+ V mov,A+ sxt KBmov(I),A+ sxt KAmov,A+ sxt KAsetl movfi,A seti KAGJsetl movfi,#(J) seti M,A M+,A+ V KBM(I),A M+2(I),A+ V GBM,2+#(I) V(I) KAM,A M+,A+ V GBmov,#+2(I) sxt(I) KAGJM+,#+2(J) V(J) M,#(J) KCGBmovsp)+,#+2(I) sxt(I) KCGBMsp)+,#(I) Msp)+,#+2(I) V(I) GDKAM,*(sp) movsp)+,I M+,2(I) M'C KBmovC',J M(I),J movC,A KAmovC',J M,J movC,A KCGBmovC(I),J Msp)+,J movC,#(I) asrC GBasrC(I) aslC GBaslC(I) ash,A KBash(I),A KAash,A GAashc,I mov,A mov+,A+ KCGAashcsp)+,I mov,A mov+,A+ GDKCmov(sp),I mov(I),I+ movI),I ashcsp)+,I mov,*(sp) add2,(sp) mov+,*(sp)+ bicC,A' bisC,A KAbicC,A' bisC,A GBbicC,#(I) bisC,#(I) KAGJbicC,#(J) bisC,#(J) GBKIbicC,#(I) bisC,#(I) KCGBbicC,#(I) bisCsp)+,#(I) movof,I GBmovof(I),I GEtst X0tst+ X1tst X0cmp+,B X1M,B X0M+,B+ X1GBtst(I) X0tst+2(I) X1GBtst(I) X0cmp+2(I),B X1GBM(I),B X0M+2(I),B+ X1GAtst X0tst+ X1GAtst X0cmp+,B X1GAM,B X0M+,B+ X1GBKJM(I),"(J) X0M+2(I),"+2(J) X1GAKJM,"(J) X0M+,"+2(J) X1/bit0,A /X0bit,A+ X1GB/bit0,"(I) /X0bit,"+2(I) X1GA/bit0,I /X0bit,I+ X1HAclrC(sp) mov,-(sp) GBmov(I),-(sp) mov+,-(sp) mov,-(sp) GCM'sp) GCM,(sp) GCKBM(I),(sp) GCKAM,(sp) GCsxt(sp) GAsetl movfi,-(sp) seti ??????)?6?<?C?C?L?V?V?d?s??TT?? 0T=h?????????T?0T?@?Q?Q?c?vT???T? ?? ? ???T?T?+?+?6?6??F??F?U?a?s???+???s??????T?T?+?+??F??F??T?????T?+??F.<<T?gTw???T????D?i<<?????D?i?T??<???D?iA?aT???g?? EU??T?+?6??F?l?v??????????????'??6??A??Xnntt?TTTTT??? T? % 1 F P ^ ?q ? T?    ?  T? ?5 ?R ?TTT??F   ?  T? ?R ? T? ?w    ?tT ? T??? F   ?  T? ?R       ' ?4 > ?Y ?z  ?  T? ' ?B nna ttk ?z ?z ??TT?T?T?+?+???F??F}      ? ? ?$ T7 ?TZ ??+??Fv    ?$ T7 ?TZ ? ?? ?? ? ? ? ? ? ? ????.??;??Gjhh !%&brcrP()*+66,6-.701FhGhHIJ:KhLNhUhOTfd3489:;[vRSTVWXl\VV V!VPFVGVNOBUKLj8h7h"h#h$h%h(h)h*h+h-h.hQ0h<8=8>8?8@8A8B8C8D8E8HhIhOhjv()70:8L1L2L3L4L5)L66L7<L8CL9LL10VL11dL12sL13L14L15L16L17L18L19 L200L21=L22hL23L24L25L26L27L28L29L30L310L32@L33QL34cL35vL36L37L38L40L41 L42 add1L43add2L44add3+L45+add46L466add5FL47FL48UL49aaddl1sL50saddl2L51L53L55L56L61L62L63L64addq1.L69.addq1a<L70<addq2TL71Taddq3gL72gaddq4wL73waddq4aL74addq5L75addq6L76addq7L77addq8L78addq9L79addq9aDL80Daddq10iL81iL89L90L91L92L99AL100aL101L102L104L105 L106EL107UL113lL114vL115L116L117L118L119L120L121L122L123'L1246L125AL126Xmove1nL127nmove2tL128tmove3L129move4L130move5L131move6L132move7L133move8L134move9L135move10L136move11L137move12L138L139 L140 L141% L1421 move13aF L143F L144P L145^ L146q L147 L148 move13 L149 move14 L150 move14a L151 move15 L152 L153 move16 L154 L1555 move17R L156R L175w L176 L177 L183 L184 L187 L195 L196 L197 L198 L199 L200' L2014 L202> L203Y L204z L205 L206 L207 fas1 L208 L209' L210B L212a L214k L215z L226} L227 lcmp1 L228 L229 L230 lcmp2 L231 L232 L233 lcmp3$ L234$ lcmp47 L2357 lcmp5Z L236Z L242v L243 L249 L250 L251 L252 L253 L254 L255 L256L257L258.L259;L260G_regtab#cr106cr70hcr32cr37cr100rcr80cr40cr42cr436cr45cr49cr72cr73cr74:cr75hcr79Tcr102dcr51cr52cr56cr57cr58cr59cr91vcr82cr86cr16lcr92L39 L52+L54sL57L58L59+L60FL65L66L67+L68FL82<L83L84L85L86L87DL88iL93<L94L95L96L97DL98iL103gL108L109L110+L1116L112F_efftab#~ci70Vci80ci78ci79Bci75ci76ci16L157L158L159L160L161L162L163L164L165L166F L167 L168 L169 L170 L171 L172R L173 L174 L178L179L180L181tL182L185L186L188F L189 L190 L191 L192 L193 L194R _cctab#cc608resthcc81L211nL213tL216L217L218L219L220L221L222+L223L224L225FL237L238L239L240+L241FL244 L245 L246$ L2477 L248Z _sptab#&cs106vcs40cs58cs56L181tL182L185L186L188F L189 L190 L191 L192 L193 L194R _cctab#cc608resthcc81L211nL213tL216L217L218/ / c code tables-- compile to register / .globl _regtab .data _regtab=. 106.; cr106 30.; cr70 31.; cr70 32.; cr32 33.; cr32 37.; cr37 38.; cr37 98.; cr100 99.; cr100 80.; cr80 40.; cr40 41.; cr40 / - like + 42.; cr42 43.; cr43 14.; cr43 44.; cr43 45.; cr45 46.; cr40 55.; cr40 48.; cr40 49.; cr49 70.; cr70 71.; cr70 72.; cr72 73.; cr73 74.; cr74 75.; cr75 76.; cr72 78.; cr70 85.; cr70 79.; cr79 102.; cr102 51.; cr51 52.; cr52 56.; cr56 57.; cr57 58.; cr58 59.; cr59 91.; cr91 82.; cr82 83.; cr82 84.; cr82 86.; cr86 87.; cr86 88.; cr86 16.; cr16 92.; cr92 0 .text / goto cr102: %a,n jmp A1 %n*,n F* jmp #1(R) / call cr100: %a,n jsr pc,IA1 %n*,n F* jsr pc,#1(R) %n,n F jsr pc,(R) / addressible cr106: %z,n clr R %zf,n clrf R %a,n %ad,n movB1 A1,R %af,n movof A1,R %n*,n %nd*,n F* movB1 #1(R),R %nf*,n F* movof #1(R),R %al,n mov A1+,R+ mov A1,R %nl*,n F* mov #1+2(R),R+ mov #1(R),R / ++,-- postfix cr32: %a,1 movB1 A1',R I'B1 A1 %aw,n mov A1',R I A2,A1 %e*,1 F1* movB1 #1(R1),R I'B1 #1(R1) %n*,1 F* movB1 #1(R),-(sp) I'B1 #1(R) movB1 (sp)+,R %ew*,n F1* mov #1(R1),R I A2,#1(R1) %nw*,n F* mov #1(R),-(sp) I A2,#1(R) mov (sp)+,R %al,1 F I $1,A1+ V A1 %el*,1 F1* mov #1+2(R1),R+ mov #1(R1),R I $1,#1+2(R1) V #1(R1) %nl*,1 F* mov #1+2(R),-(sp) mov #1(R),-(sp) add $1,#1+2(R) V #1(R) mov (sp)+,R mov (sp)+,R+ / - unary, ~ cr37: %n,n %nf,n F IBF R %nl,n F I R I R+ V R / = cr80: %a,n %ad,nf S movB1 R,A1 %af,nf S movfo R,A1 %nd*,af F* S movf R,#1(R) %n*,aw F* movB1 A2,#1(R) movB1 #1(R),R %nf*,af F* S movfo R,#1(R) %n*,e F* S1 movB1 R1,#1(R) movB1 R1,R %ed*,nf S F1* movf R,#1(R1) %ef*,nf S F1* movfo R,#1(R1) %n*,n %nd*,nf FS* S movB1 R,*(sp)+ %nf*,nf FS* S movfo R,*(sp)+ %al,nl S mov R+,A1+ mov R,A1 %el*,nl S F1* mov R+,2+#1(R1) mov R,#1(R1) %nl*,nl FS* S mov R,*(sp) add $2,(sp) mov R+,*(sp)+ / field assign, value in reg. cr16: %a,n S bicB1 Z,A1' bisB1 R,A1 %e*,n % [fas1] %n*,n SS F* bicB1 Z,#1(R) bisB1 (sp),#1(R) mov (sp)+,R / +, -, |, &~, << cr40: %n,z F %n,1 F I' R %[add1:] %n,aw %nf,ad F IB2 A2,R %[add2:] %n,ew* %nf,ed* F S1* IB2 #2(R1),R %[add3:] %n,e %nf,ef F S1 IBF R1,R %[add4:] %n,nw* %nf,nd* SS* F IB2 *(sp)+,R %[add5:] %n,n %nf,nf SS F IBF (sp)+,R %nl,c F I A2,R+ V R %nl,al F I A2,R I A2+,R+ V R %[addl1:] %nl,el F S1 I R1+,R+ V R I R1,R %[addl2:] %nl,nl SS F I (sp)+,R I (sp)+,R+ V R / ^ -- xor cr49: %n,e % [add3] %n,n FS S xor R,(sp) mov (sp)+,R %nl,el % [addl1] %nl,nl SS F I R,(sp) mov (sp)+,R I R+,(sp) mov (sp)+,R+ / >> (all complicated cases taken care of by << -) cr45: %n,1 F asr R / * -- R must be odd on integers cr42: %n,aw %nf,ad % [add1] %n,ew* %nf,ed* % [add2] %n,e %nf,ef % [add3] %n,n %nf,nf % [add5] / / R must be odd on integers cr43: %n,aw F T div A2,R- %n,ew* F T S1* div #2(R1),R- %n,e F T S1 div R1,R- %n,n SS F T div (sp)+,R- %nf,ad % [add1]  %nf,ed* % [add2] %nf,ef % [add3] %nf,nf % [add5] / =+, =-, =|, =&~ cr70: %[addq1:] %aw,aw I A2,A1' mov A1,R %[addq1a:] %a,aw %ad,ad movB1 A1',R IBF A2,R movB1 R,A1 %[addq2:] %aw,nw* S* I #2(R),A1' mov A1,R %[addq3:] %aw,n S I R,A1' mov A1,R %[addq4:] %ew*,nw* S* F1* I #2(R),#1(R1) mov #1(R1),R %[addq4a:] %ad,ef movf A1',R S1 IBF R1,R movf R,A1 %[addq5:] %a,n %ad,nf SS movB1 A1',R IBF (sp)+,R movB1 R,A1 %[addq6:] %af,nf SS movof A1',R IBF (sp)+,R movfo R,A1 %[addq7:] %ew*,n S F1* I R,#1(R1) mov #1(R1),R %[addq8:] %nw*,n SS F* I (sp)+,#1(R) mov #1(R),R %[addq9:] %n*,n FS* SS movB1 *2(sp),R IBF (sp)+,R movB1 R,*(sp)+ %[addq9a:] %nd*,nf SS F* movB1 #1(R),R IBF (sp)+,R movB1 R,#1(R) %[addq10:] %nf*,nf SS F* movof #1(R),R1 IBF (sp)+,R1 movfo R1,#1(R) movf R1,R / =*, =<< (for integer multiply, R must be odd) cr72: %a,aw %ad,ad % [addq1a] %af,nf % [addq6] %ad,ef % [addq4a] %a,n %ad,nf % [addq5] %n*,n % [addq9] %nd*,nf % [addq9a] %nf*,nf % [addq10] / =/ ; R must be odd on integers cr73: %a,aw movB1 A1',R sxt R- divBF A2,R- movB1 R-,A1 %a,n SS movB1 A1',R sxt R- div (sp)+,R- movB1 R-,A1 %e*,n SS F1* movB1 #1(R1),R sxt R- div (sp)+,R- movB1 R-,#1(R1) %n*,n FS* SS movB1 *2(sp),R sxt R- div (sp)+,R- movB1 R-,*(sp)+ %ad,ad % [addq1a] %ad,ef % [addq4a] %ad,nf % [addq5] %af,nf % [addq6] %nd*,nf % [addq9a] %nf*,nf % [addq10] / =mod; R must be odd on integers cr74: %a,aw movB1 A1',R sxt R- div A2,R- movB1 R,A1 %a,n SS movB1 A1',R sxt R- div (sp)+,R- movB1 R,A1 %e*,n SS F1* movB1 #1(R1),R sxt R- div (sp)+,R- movB1 R,#1(R1) %n*,n FS* SS movB1 *2(sp),R sxt R- div (sp)+,R- mov R,*(sp)+ / =^ -- =xor cr79: %aw,n % [addq3] %ab,n SS movb A1',R xor R,(sp) mov (sp)+,R movb R,A1 %n*,n FS* movB1 *(sp),-(sp) S xor R,(sp) movB1 (sp)+,R movB1 R,*(sp)+ / =>> (all complicated cases done by =<< -) cr75: %a,1 asrB1 A1' movB1 A1,R %n*,1 F* asrB1 #1(R) movB1 #1(R),R / << for longs cr91: %nl,aw % [add1] %nl,ew* % [add2] %nl,e % [add3] %nl,nw* % [add4] %nl,n % [add5] / int -> float cr51: %aw,n movif A1,R %nw*,n F* movif #1(R),R %n,n F movif R,R / float, double -> int cr52: %nf,n F movfi R,R / double (float) to long cr56: %nf,n F setl movfi R,-(sp) mov (sp)+,R mov (sp)+,R+ seti / long to double cr57: %al,n setl movif A1,R seti %nl*,n F* setl movif #1(R),R seti %nl,n FS setl movif (sp)+,R seti / integer to long cr58: %n,n F1! sxt R / long to integer cr59: %al,n mov A1+,R %nl*,n F* mov #1+2(R),R %nl,n F mov R+,R / *, /, remainder for longs. cr82: %nl,nl SS FS jsr pc,I add $10,sp / =*, =/, =rem for longs / Operands of the form &x op y, so stack space is known. cr86: %n,nl SS FS jsr pc,I add $6,sp / / c code tables -- compile for side effects. / Also set condition codes properly (except for ++, --) / .globl _efftab .data _efftab=. 30.; ci70 31.; ci70 32.; ci70 33.; ci70 80.; ci80 70.; ci70 71.; ci70 / - like + 78.; ci78 79.; ci79 85.; ci78 75.; ci75 76.; ci76 16.; ci16 0 .text / = ci80: %[move1:] %a,z %ad,zf I'B1 A1 %[move2:] %n*,z %nd*,zf F* I'B1 #1(R) %[move3:] %a,aw %ab,a IBE A2,A1 %[move4:] %ab,n* %a,nw* S* IBE #2(R),A1 %[move5:] %a,n S IB1 R,A1 %[move6:] %n*,aw %nb*,a F* IBE A2,#1(R) %[move7:] %n*,ew* %nb*,e* F* S1* IBE #2(R1),#1(R) %[move8:] %n*,e F* S1 IB1 R1,#1(R) %[move9:] %e*,nw* %eb*,n* S* F1* IBE #2(R),#1(R1) %[move10:] %e*,n S F1* IB1 R,#1(R1) %[move11:] %n*,nw* %nb*,n* FS* S* IBE #2(R),*(sp)+ %[move12:] %n*,n FS* S IB1 R,*(sp)+ %aw,nf S movfi R,A1 %ew*,nf S F1* movfi R,#1(R1) %al,z clr A1 clr A1+ %nl*,z F* clr #1(R) clr 2+#1(R) %[move13a:] %al,c I A2,A1+ V A1 %al,aw mov A2,A1+ sxt A1 %al,nw* S* mov #2(R),A1+ sxt A1 %al,n S mov R,A1+ sxt A1 %al,nf S setl movfi R,A1 seti %el*,nf S F1* setl movfi R,#1(R1) seti %[move13:] %al,al I A2,A1 I A2+,A1+ V A1 %[move14:] %al,nl* S* I #2(R),A1 I #2+2(R),A1+ V A1 %[move14a:] %nl*,c F* I A2,2+#1(R) V #1(R) %[move15:] %al,nl S I R,A1 I R+,A1+ V A1 %nl*,aw F* mov A2,#1+2(R) sxt #1(R) %[move16:] %el*,nl S F1* I R+,#1+2(R1) V #1(R1) I R,#1(R1) %nl*,n SS F* mov (sp)+,#1+2(R) sxt #1(R) %[move17:] %nl*,nl SS F* I (sp)+,#1(R) I (sp)+,#1+2(R) V #1(R) / =| and =& ~ ci78: %a,a % [move3] %a,n % [move5] %n*,a % [move6] %n*,e* % [move7] %n*,e % [move8] %e*,n* % [move9] %e*,n % [move10] %n*,n* % [move11] %n*,n % [move12] %al,c % [move13a] %al,al % [move13] %al,nl* % [move14] %al,nl % [move15] %nl*,c % [move14a] %el*,nl % [move16] %nl*,nl % [move17] / =^ ci79: %al,nl % [move15] %el*,nl % [move16] %nl*,nl FS* S I R,*(sp) mov (sp)+,R I R+,2(R) / =+ ci70: %n*,z %a,z %a,1 I'B1 A1 %aw,aw % [move3] %aw,nw* % [move4] %aw,n % [move5] %n*,1 % [move2] %ew*,nw* % [move9] %a,nw* S* movB1 A1',R1 I #2(R),R1 movB1 R1,A1 %a,n S movB1 A1',R1 I R,R1 movB1 R1,A1 %ew*,n % [move10] %nw*,n % [move12] %n*,n SS F* movB1 #1(R),R1 I (sp)+,R1 movB1 R1,#1(R) %al,c % [move13a]  %al,al % [move13] %al,nl* % [move14] %al,nl % [move15] %nl*,c % [move14a] %el*,nl % [move16] %nl*,nl % [move17] / =>> (all harder cases handled by =<< -) ci75: %a,1 asrB1 A1 %n*,1 F* asrB1 #1(R) / =<< ci76: %a,1 aslB1 A1 %n*,1 F* aslB1 #1(R) %r,aw ash A2,A1 %r,nw* S* ash #2(R),A1 %r,n S ash R,A1 / =<< for longs cr92: %al,aw F ashc A2,R mov R,A1 mov R+,A1+ %al,n SS F ashc (sp)+,R mov R,A1 mov R+,A1+ %nl*,n FS* SS mov 2(sp),R mov 2(R),R+ mov (R),R ashc (sp)+,R mov R,*(sp) add $2,(sp) mov R+,*(sp)+ / field = ... ci16: %a,a bicB1 Z,A1' bisB1 A2,A1 %a,n S bicB1 Z,A1' bisB1 R,A1 %n*,a F* bicB1 Z,#1(R) bisB1 A2,#1(R) %[fas1:] %e*,n S F1* bicB1 Z,#1(R1) bisB1 R,#1(R1) %n*,e F* S1 bicB1 Z,#1(R) bisB1 R1,#1(R) %n*,n SS F* bicB1 Z,#1(R) bisB1 (sp)+,#1(R) / / c code tables-- set condition codes / .globl _cctab .data _cctab=. 106.; cc60 28.; rest 55.; rest 34.; rest 35.; rest 36.; rest 37.; rest 40.; rest 41.; rest 42.; rest 43.; rest 45.; rest 46.; rest 81.; cc81 / & as in "if ((a&b)==0)" 48.; rest 60.; cc60 61.; cc60 62.; cc60 63.; cc60 64.; cc60 65.; cc60 66.; cc60 67.; cc60 68.; cc60 69.; cc60 72.; rest 73.; rest 79.; rest 0 .text / relationals cc60: %a,z %ad,zf % [move1] %af,z movof A1,R %n*,z %nd*,zf % [move2] %nf*,z F* movof #1(R),R %n,z %nf,zf FC %aw,aw %ab,ab % [move3] %nw*,aw %nb*,ab % [move6] %n,aw %nf,ad % [add1] %nw*,ew* %nb*,eb* % [move7] %nw*,e % [move8] %n,ew* %nf,ed* % [add2] %n,e %nf,ef % [add3] %nw*,nw* %nb*,nb* % [move11] %nw*,n % [move12] %n,n %nf,nf % [add5] %al,z tst A1 X0 tst A1+ X1 %al,c tst A1 X0 cmp A1+,A2 X1 %[lcmp1:] %al,al I A1,A2 X0 I A1+,A2+ X1 %nl*,z F* tst #1(R) X0 tst #1+2(R) X1 %nl*,c F* tst #1(R) X0 cmp #1+2(R),A2 X1 %[lcmp2:] %nl*,al F* I #1(R),A2 X0 I #1+2(R),A2+ X1 %nl,z F tst R X0 tst R+ X1 %nl,c F tst R X0 cmp R+,A2 X1 %[lcmp3:] %nl,al F I R,A2 X0 I R+,A2+ X1 %[lcmp4:] %nl*,el* F* S1* I #1(R),#2(R1) X0 I #1+2(R),#2+2(R1) X1 %[lcmp5:] %nl,el* F S1* I R,#2(R1) X0 I R+,#2+2(R1) X1 / & as in "if ((a&b) ==0)" cc81: %a,a % [move3] %n*,a % [move6] %n,a % [add1] %n,e % [add3] %n,n % [add5] %al,c /bit $0,A1 /X0 bit A2,A1+ X1 %nl*,c F* /bit $0,#2(R) /X0 bit A2,#2+2(R) X1 %al,al % [lcmp1] %nl*,al % [lcmp2] %nl,al % [lcmp3] %nl*,el* % [lcmp4] %nl,el* % [lcmp5] %nl,c F /bit $0,R /X0 bit A2,R+ X1 / set codes right rest: %n,n %nf,nf H / / c code tables-- expression to -(sp) / .globl _sptab .data _sptab=. 106.; cs106 40.; cs40 41.; cs40 55.; cs40 48.; cs40 58.; cs58 56.; cs56 0 .text / name cs106: %z,n %zf,n clrB1 -(sp) %aw,n mov A1,-(sp) %nw*,n F* mov #1(R),-(sp) %al,n mov A1+,-(sp) mov A1,-(sp) / +, -, |, &~ cs40: %n,1 FS I' (sp) %n,aw FS I A2,(sp) %n,nw* FS S* I #2(R),(sp) %n,n FS S I R,(sp) / integer to long cs58: %n,n FS sxt -(sp) / float to long cs56: %nf,n F setl movfi R,-(sp) seti nf H / / c code tables-- expression to -(sp) / .globl _spt/ C library -- abort .globl _abort iot = 4 _abort: mov r5,-(sp) mov sp,r5 iot mov (sp)+,r5 rts pc t / name cs106: %z,n %zf,n clrB1 -(sp) %aw,n mov A1,-(sp) %nw*,n F* mov #1(R),-(sp) %al,n mov A1+,-(sp) mov A1,-(sp) / +, -, |, &~ cs40: %n,1 FS I' (sp) %n,aw FS I A2,(sp) %n,nw* FS S* I #2(R),(sp) %n,n FS S I R,(sp) / integer to long cs58: %n,n FS sxt -(sp) / float to long cs56: %nf,n F setl movfi R,-(sp) seti nf H / / c code tables-- expression to -(sp) / .globl _spt/ abs - int absolute value. / fabs - floating abs .globl _abs _abs: mov 2(sp),r0 bge 1f neg r0 1: rts pc .globl _fabs _fabs: movf 2(sp),fr0 absf fr0 rts pc ) %nw*,n F* mov #1(R),-(sp) %al,n mov A1+,-(sp) mov A1,-(sp) / +, -, |, &~ cs40: %n,1 FS I' (sp) %n,aw FS I A2,(sp) %n,nw* FS S* I #2(R),(sp) %n,n FS S I R,(sp) / integer to long cs58: %n,n FS sxt -(sp) / float to long cs56: %nf,n F setl movfi R,-(sp) seti nf H / / c code tables-- expression to -(sp) / .globl _spt/ access(file, request) / test ability to access file in all indicated ways / 1 - read / 2 - write / 4 - execute .globl _access .globl csv, cret .comm _errno,2 access = 33. _access: jsr r5,csv mov 4(r5),0f+2 mov 6(r5),0f+4 clr r0 sys 0; 0f .data 0: sys access; ..; .. .text bec 1f mov r0,_errno mov $-1,r0 1: jmp cret S I R,(sp) / integer to long cs58: %n,n FS sxt -(sp) / float to long cs56: %nf,n F setl movfi R,-(sp) seti nf H / / c code tables-- expression to -(sp) / .globl _spt/ C library -- acct(file): turn accounting on / acct(0): turn it off. .globl _acct, csv, cret, cerror acct = 51. _acct: jsr r5,csv mov 4(r5),0f sys indir; 9f .data 9: sys acct; 0:.. .text bec 1f jmp cerror 1: clr r0 jmp cret sys 0; 0f .data 0: sys access; ..; .. .text bec 1f mov r0,_errno mov $-1,r0 1: jmp cret S I R,(sp) / integer to long cs58: %n,n FS sxt -(sp) / float to long cs56: %nf,n F setl movfi R,-(sp) seti nf H / / c code tables-- expression to -(sp) / .globl _spt/ C library - alarm, pause .globl _alarm .globl _pause alarm = 27. pause = 29. .globl cerror _alarm: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 sys alarm mov (sp)+,r5 rts pc _pause: mov r5,-(sp) mov sp,r5 sys pause bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .; .. .text bec 1f mov r0,_errno mov $-1,r0 1: jmp cret S I R,(sp) / integer to long cs58: %n,n FS sxt -(sp) / float to long cs56: %nf,n F setl movfi R,-(sp) seti nf H / / c code tables-- expression to -(sp) / .globl _spt/ storage allocator for use with C / / Copyright, Bell Laboratories, 1975 / / / hand-tooled from C compilation to modify save-return / so that it can be called from within the C save / when running with coroutines / /# //* / * C storage allocator / * (circular first fit strategy) / */ /#define BLOK 512 /#define BUSY 01 / /char *allocs[2] { /*initial empty arena*/ / &allocs[1], / &allocs[0] /}; /struct { int word; }; /char **allocp &allocs[1]; /*current search pointer*/ /char **alloct &allocs[1]; /*top of arena (last cell)*/ / /alloc(nbytes) /{ / register int nwords; / register char **p, **q; / static char **t; / / allocs[0].word =| BUSY; /*static initialization*/ / allocs[1].word =| BUSY; / / nwords = (nbytes+(2*sizeof(p)-1))/sizeof(p); / for(p=allocp;;) { / do { / if((p->word&BUSY)==0) { / while(((q = *p)->word&BUSY)==0) / *p = *q; / if(q >= &p[nwords]) / goto found; / } / q = p; / p = p->word & ~BUSY; / } while(q>=allocp || pword =| BUSY; / alloct = (*t = &t[BLOK]-1); / *alloct = allocs; / alloct->word =| BUSY; / } /found: / allocp = &p[nwords]; / if(q>allocp) / *allocp = *p; / *p = allocp.word|BUSY; / return(p+1); /} / /free(p) /char **p; /{ / allocp = p-1; / allocp->word =& ~BUSY; /} .globl _allocs .data _allocs=. 2+_allocs _allocs .globl _allocp .data _allocp=. 2+_allocs .globl _alloct .data _alloct=. 2+_allocs .globl _alloc .globl _sbrk .text _alloc: mov r5,-(sp) mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) bis $1,_allocs bis $1,2+_allocs mov 4(r5),r4 add $3,r4 asr r4 mov _allocp,r3 jbr L6 L7:mov r3,r2 mov (r3),r3 bic $!177776,r3 cmp r2,_allocp jhis L6 cmp r3,_allocp jlo L6 mov $2000,-(sp) jsr pc,*$_sbrk tst (sp)+ mov r0,t mov r0,*_alloct cmp $177777,r0 jne L11 4 L11:mov _alloct,r0 add $2,r0 cmp t,r0 jeq L12 bis $1,*_alloct L12:mov t,r0 add $1776,r0 mov r0,*t mov r0,_alloct mov $_allocs,*_alloct bis $1,*_alloct L6:bit $1,(r3) jeq L8 jbr L7 L20001:mov (r2),(r3) L8:mov (r3),r2 bit $1,(r2) jeq L20001 mov r4,r0 asl r0 add r3,r0 cmp r2,r0 jlo L7 mov r4,r0 asl r0 add r3,r0 mov r0,_allocp cmp r2,r0 jlos L13 mov (r3),*_allocp L13:mov _allocp,r0 bis $1,r0 mov r0,(r3) mov r3,r0 add $2,r0 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 mov (sp)+,r5 rts pc .globl _free .text _free: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 add $177776,r0 mov r0,_allocp bic $!177776,*_allocp mov (sp)+,r5 rts pc .bss t: .=.+2 _allocs,*_alloct bis $1,*_alloct L6:bit $1,(r3) jeq L8 jbr L7 L20001:mov (r2),(r3) L8:mov (r3),r2 / C library -- ascii to floating / f = atof(p) / char *p; ldfps = 170100^tst stfps = 170200^tst .globl _atof .globl csv, cret _atof: jsr r5,csv stfps -(sp) ldfps $200 movf fr1,-(sp) clr -(sp) clrf fr0 clr r2 mov 4(r5),r3 1: movb (r3)+,r0 cmp $' ,r0 beq 1b cmpb r0,$'- bne 2f inc (sp) 1: movb (r3)+,r0 2: sub $'0,r0 cmp r0,$9. bhi 2f jsr pc,digit br 1b inc r2 br 1b 2: cmpb r0,$'.-'0 bne 2f 1: movb (r3)+,r0 sub $'0,r0 cmp r0,$9. bhi 2f jsr pc,digit dec r2 br 1b 2: cmpb r0,$'E-'0 beq 3f cmpb r0,$'e-'0 bne 1f 3: clr r4 clr r1 cmpb (r3),$'+ bne 3f inc r3 3: cmpb (r3),$'- bne 3f inc r4 inc r3 3: movb (r3)+,r0 sub $'0,r0 cmp r0,$9. bhi 3f mul $10.,r1 add r0,r1 br 3b 3: tst r4 bne 3f neg r1 3: sub r1,r2 1: movf $one,fr1 mov r2,-(sp) beq 2f bgt 1f neg r2 1: cmp r2,$38. blos 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: mulf fr1,fr0 cfcc bvc 2f movf $huge,fr0 2: out: tst (sp)+ beq 1f negf fr0 1: movf (sp)+,fr1 ldfps (sp)+ jmp cret / / digit: cmpf $big,fr0 cfcc blt 1f mulf $ten,fr0 movif r0,fr1 addf fr1,fr0 rts pc 1: add $2,(sp) rts pc / .data ten20: 61530;153446;133427;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: matoi(ap) char *ap; { register n, c; register char *p; int f; p = ap; n = 0; f = 0; loop: while(*p == ' ' || *p == ' ') p++; if(*p == '-') { f++; p++; goto loop; } while(*p >= '0' && *p <= '9') n = n*10 + *p++ - '0'; if(f) n = -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C return sequence which / sets errno, returns -1. .globl cerror .comm _errno,2 cerror: mov r0,_errno mov $-1,r0 mov r5,sp mov (sp)+,r5 rts pc f++; p++; goto loop; } while(*p >= '0' && *p <= '9') n = n*10 + *p++ - '0'; if(f) n = -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C library -- chdir / error = chdir(string); .globl _chdir, cerror _chdir: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys chdir; 0:.. 9') n = n*10 + *p++ - '0'; if(f) n = -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C library -- chmod / error = chmod(string, mode); .globl _chmod, cerror _chmod: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys chmod; 0:..; .. '; if(f) n = -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C library -- chown / error = chown(string, owner); .globl _chown, cerror _chown: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys chown; 0:..; .. ; if(f) n = -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C library -- close / error = close(file); .globl _close, cerror _close: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 sys close bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc 0 mov (sp)+,r5 rts pc .data 9: sys chown; 0:..; .. ; if(f) n = -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C library -- creat / file = creat(string, mode); / / file == -1 if error .globl _creat, cerror _creat: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: mov (sp)+,r5 rts pc .data 9: sys creat; 0:..; .. -n; return(n); } 27;075200 / one = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C runtime startoff .globl savr5 .globl _exit .globl start .globl _main start: setd mov sp,r0 mov (r0),-(sp) tst (r0)+ mov r0,2(sp) jsr pc,_main cmp (sp)+,(sp)+ mov r0,(sp) jsr pc,*$_exit sys exit .bss savr5: .=.+2 .data .=.+2 / loc 0 for I/D; null ptr points here. e = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m/ C register save and restore -- version 12/74 .globl csv .globl cret csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) / jsr part is sub $2,sp cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc nts here. e = 40200 ten = 41040 big = 56200 huge = 77777 s 1f clrf fr0 tst (sp)+ bmi out movf $huge,fr0 br out 1: cmp r2,$21. bne 3f mulf ten20,fr1 br 2f 3: mulf $ten,fr1 sob r2,1b 2: tst (sp)+ bge 1f divf fr1,fr0 br 2f 1: m# /* * This routine converts time as follows. * The epoch is 0000 Jan 1 1970 GMT. * The argument time is in seconds since then. * The localtime(t) entry returns a pointer to an array * containing * seconds (0-59) * minutes (0-59) * hours (0-23) * day of month (1-31) * month (0-11) * year-1970 * weekday (0-6, Sun is 0) * day of the year * daylight savings flag * * The routine corrects for daylight saving * time and will work in any time zone provided * "timezone" is adjusted to the difference between * Greenwich and local standard time (measured in seconds). * In places like Michigan "daylight" must * be initialized to 0 to prevent the conversion * to daylight time. * There is a table which accounts for the peculiarities * undergone by daylight time in 1974-1975. * * The routine does not work * in Saudi Arabia which runs on Solar time. * * asctime(tvec)) * where tvec is produced by localtime * returns a ptr to a character string * that has the ascii time in the form * Thu Jan 01 00:00:00 1970n0\\ * 01234567890123456789012345 * 0 1 2 * * ctime(t) just calls localtime, then asctime. */ char cbuf[26]; int dmsize[12] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; int timezone 5*60*60; int tzname[] { "EST", "EDT", }; int daylight 1; /* Allow daylight conversion */ /* * The following table is used for 1974 and 1975 and * gives the day number of the first day after the Sunday of the * change. */ struct { int daylb; int dayle; } daytab[] {  5, 333, /* 1974: Jan 6 - last Sun. in Nov */ 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ }; #define SEC 0 #define MIN 1 #define HOUR 2 #define MDAY 3 #define MON 4 #define YEAR 5 #define WDAY 6 #define YDAY 7 #define ISDAY 8 ctime(at) int *at; { return(asctime(localtime(at))); } localtime(tim) int tim[]; { register int *t, *ct, dayno; int daylbegin, daylend; int copyt[2]; t = copyt; t[0] = tim[0]; t[1] = tim[1]; dpadd(t, -timezone); ct = gmtime(t); dayno = ct[YDAY]; daylbegin = 119; /* last Sun in Apr */ daylend = 303; /* Last Sun in Oct */ if (ct[YEAR]==74 || ct[YEAR]==75) { daylbegin = daytab[ct[YEAR]-74].daylb; daylend = daytab[ct[YEAR]-74].dayle; } daylbegin = sunday(ct, daylbegin); daylend = sunday(ct, daylend); if (daylight && (dayno>daylbegin || (dayno==daylbegin && ct[HOUR]>=2)) && (dayno= 58) d =+ dysize(t[YEAR]) - 365; return(d - (d - t[YDAY] + t[WDAY] + 700) % 7); } gmtime(tim) int tim[]; { register int d0, d1; register *tp; static xtime[9]; extern int ldivr; /* * break initial number into * multiples of 8 hours. * (28800 = 60*60*8) */ d0 = ldiv(tim[0], tim[1], 28800); d1 = ldivr; tp = &xtime[0]; /* * generate hours:minutes:seconds */ *tp++ = d1%60; d1 =/ 60; *tp++ = d1%60; d1 =/ 60; d1 =+ (d0%3)*8; d0 =/ 3; *tp++ = d1; /* * d0 is the day number. * generate day of the week. */ xtime[WDAY] = (d0+4)%7; /* * year number */ for(d1=70; d0 >= dysize(d1); d1++) d0 =- dysize(d1); xtime[YEAR] = d1; xtime[YDAY] = d0; /* * generate month */ if (dysize(d1)==366) dmsize[1] = 29; for(d1=0; d0 >= dmsize[d1]; d1++) d0 =- dmsize[d1]; dmsize[1] = 28; *tp++ = d0+1; *tp++ = d1; xtime[ISDAY] = 0; return(xtime); } asctime(t) int *t; { register char *cp, *ncp; register int *tp; cp = cbuf; for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); ncp = &"SunMonTueWedThuFriSat"[3*t[6]]; cp = cbuf; *cp++ = *ncp++; *cp++ = *ncp++; *cp++ = *ncp++; cp++; tp = &t[4]; ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; *cp++ = *ncp++; *cp++ = *ncp++; *cp++ = *ncp++; cp = numb(cp, *--tp); cp = numb(cp, *--tp+100); cp = numb(cp, *--tp+100); cp = numb(cp, *--tp+100); cp =+ 2;  cp = numb(cp, t[YEAR]); return(cbuf); } dysize(y) { if((y%4) == 0) return(366); return(365); } numb(acp, n) { register char *cp; cp = acp; cp++; if (n>=10) *cp++ = (n/10)%10 + '0'; else *cp++ = ' '; *cp++ = n%10 + '0'; return(cp); } *cp++ = *ncp++; cp++; tp = &t[4]; ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; *cp++ = *ncp++; *cp++ = *ncp++; *cp++ = *ncp++; cp = numb(cp, *--tp); cp = numb(cp, *--tp+100); cp = numb(cp, *--tp+100); cp = numb(cp, *--tp+100); cp =+ 2; # #define STRUCT struct #define CHAR char #define BOOL char #define REG register #define INT int #define STRING char * #define PTR int * #define EXITSW break #define BEGIN { #define END } #define IF if( #define THEN ){ #define ELSE } else { #define ELIF } else if ( #define FI } #define EXITFOR break #define FOR for( #define WHILE while( #define DO ){ #define OD } #define REP do{ #define PER }while( #define DONE ); #define LOOP for(;;){ #define POOL } #define SKIP ; #define DIV / #define REM % #define NEQ ^ #define ANDF && #define ORF || #define TRUE -1 #define FALSE 0 #define LOBYTE 0377 #define HIBYTE 0177400 #define HEXMSK 017 #define maxint 32767 #define GETBLOK 512 #define RELBLOK 256 #define FREE 32767 #define BUSY 0 #define AREA struct areablk AREA { INT word; INT area; }; /*initial empty arena*/ AREA areai; AREA areaj {&areai,0}; AREA areai {&areaj,0}; AREA **areap &areai; /*current search pointer*/ AREA **areatop &areai; /*top of arena (last cell)*/ INT areanum; /*current allocation area*/ /* * storage allocator * (circular first fit strategy) */ /* accounting INT shellpid; INT getcnt; INT freecnt; INT getloop; INT freeloop; INT getbrk; INT gbgebrk; */ INT areabrk; /*end of store in some sense*/ getcell(nbytes) char *nbytes; { REG INT rbytes; REG char *p, *q; INT newbrk; IF areabrk==0 THEN areabrk=(sbrk(0)+3)&-4; FI /*DEB getcnt++; BED*/ rbytes = (nbytes+7)&-4; p=areap; LOOP REP IF (p->area)>areanum THEN WHILE ((q = p->word)->area)>areanum DO p->word = q->word; OD IF q >= &p[rbytes] THEN areap = &p[rbytes]; IF q>areap THEN areap->word = p->word; areap->area = FREE; FI p->word=areap; p->area=areanum; return(p+4); FI FI /*DEB getloop++; BED*/ q = p; p = p->word; PER q>=areap || pword=areabrk; areatop->area = (((q=areabrk)!=areatop+2) ? BUSY : FREE); areatop = (areabrk->word = newbrk-4); areabrk->area = FREE; areabrk=newbrk; areatop->word = &areaj; areatop->area=BUSY; POOL } freecell(p) char **p; { IF p THEN p =- 2; IF parea=FREE; FI } /*** from here to the end not used freearea(a) INT a; { REG CHAR **p; REG INT from; REG PTR top; from=a; top=areatop; /*DEB freecnt++; BED*/ /******* not used p = &areai; REP IF p->area >= from THEN p->area=FREE; FI /*DEB freeloop++; BED*/ /****not used p=p->word; PER p!= top DONE } copyarea(a,to) INT a, to; { REG CHAR **p; REG INT from; REG PTR top; from=a; top=areatop; p = &areai; REP IF p->area == from THEN p->area=to; FI p=p->word; PER p!= top DONE } garbage() { REG CHAR **p, **q; REG PTR top; top=areatop; areap = p = &areai; REP IF p->area>areanum THEN WHILE ((q = p->word)->area)>areanum DO p->word = q->word; OD areap=p; FI q = p; p = p->word; PER p!=top DONE IF areatop>=q+(RELBLOK+4) DIV 2 ANDF (q->area)>areanum THEN brk(areabrk=(areabrk-RELBLOK)&-RELBLOK); q->word=areatop=areabrk-4; areatop->word = &areaj; areatop->area = BUSY; /*DEB gbgebrk++; BED*/ /**** not used FI } setarea(p,a) char **p; int a; { *(p-1)=a; } *****/ NE } garbage() { REG CHAR **p, **q; REG PTR top; top=areatop; areap = p = &areai; REP IF p->area>areanum THEN WHILE ((q = p->word)->area)>areanum DO p->word = q->word; OD areap=p; FI q = p; p = p->word; PER p!=top DONE IF areatop>=q+(RELBLOK+4) DIV 2 ANDF (q->area)>areanum THEN brk(areabrk=(areabrk-RELBLOK)&-RELBLOK); q->word=areatop=achroot = 60. .globl _chroot, cerror _chroot: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys chroot; 0:.. REG CHAR **p, **q; REG PTR top; top=areatop; areap = p = &areai; REP IF p->area>areanum THEN WHILE ((q = p->word)->area)>areanum DO p->word = q->word; OD areap=p; FI q = p; p = p->word; PER p!=top DONE IF areatop>=q+(RELBLOK+4) DIV 2 ANDF (q->area)>areanum THEN brk(areabrk=(areabrk-RELBLOK)&-RELBLOK); q->word=areatop=a/ C library -- dup / f = dup(of) / f == -1 for error dup = 41. .globl _dup, cerror _dup: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 sys dup bec 1f jmp cerror 1: mov (sp)+,r5 rts pc *p, **q; REG PTR top; top=areatop; areap = p = &areai; REP IF p->area>areanum THEN WHILE ((q = p->word)->area)>areanum DO p->word = q->word; OD areap=p; FI q = p; p = p->word; PER p!=top DONE IF areatop>=q+(RELBLOK+4) DIV 2 ANDF (q->area)>areanum THEN brk(areabrk=(areabrk-RELBLOK)&-RELBLOK); q->word=areatop=achar *sys_errlist[] { "Error 0", "Not super-user", "No such file or directory", "No such process", "Interrupted system call", "I/O error", "No such device or address", "Arg list too long", "Exec format error", "Bad file number", "No children", "No more processes", "Not enough core", "Permission denied", "Bad address", "Block device required", "Mount device busy", "File exists", "Cross-device link", "No such device", "Not a directory", "Is a directory", "Invalid argument", "File table overflow", "Too many open files", "Not a typewriter", "Text file busy", "File too large", "No space left on device", "Illegal seek", "Read-only file system", "Too many links", "Broken pipe", "No entries left", "Invalid operation", "No message", "Not allocated", "Invalid ioctl operation", }; int sys_nerr { sizeof sys_errlist/sizeof sys_errlist[0] }; nt device busy", "File exists", "Cross-device link", "No such device", "Not a directory", "Is a directory", "Invalid argument", "File table/ C library -- execl / execl(file, arg1, arg2, ... , 0); / .globl _execl, cerror _execl: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov r5,r0 add $6,r0 mov r0,0f+2 sys 0; 9f jmp cerror .data 9: sys exec; 0:..; .. ", "Invalid operation", "No message", "Not allocated", "Invalid ioctl operation", }; int sys_nerr { sizeof sys_errlist/sizeof sys_errlist[0] }; nt device busy", "File exists", "Cross-device link", "No such device", "Not a directory", "Is a directory", "Invalid argument", "File table/ C library -- execv / execv(file, argv); / / where argv is a vector argv[0] ... argv[x], 0 / last vector element must be 0 / / The _exectrap flags is used by the debugger and causes / a trace trap on the first instruction of the executed instruction / to give a chance to set breakpoints. .globl _execv, cerror .comm __exectrap,2 rtt = 6 _execv: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 tst __exectrap beq 1f mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f jmp cerror .data 9: sys exec; 0:..; .. v / execv(file, argv); / / where argv is a vector argv[0] ... argv[x], 0 / last vector element must be 0 / / The _exectrap flags is used by the debugger and causes / a trace trap on the first instruction of the executed instruction / to give a chance to set breakpoints. .globl _execv, cerror .comm __exectrap,2 rtt = 6 _execv: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 tst __exectrap beq 1f mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f jmp cerror .data 9: / C library -- exit / exit(code) / code is return in r0 to system .globl _exit _exit: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 sys exit trap flags is used by the debugger and causes / a trace trap on the first instruction of the executed instruction / to give a chance to set breakpoints. .globl _execv, cerror .comm __exectrap,2 rtt = 6 _execv: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 tst __exectrap beq 1f mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f jmp cerror .data 9: / C runtime startoff / with floating point interpreter .globl savr5 .globl fptrap .globl _exit .globl _main start: sys signal; 4; fptrap setd mov sp,r0 mov (r0),-(sp) tst (r0)+ mov r0,2(sp) jsr pc,_main cmp (sp)+,(sp)+ mov r0,(sp) jsr pc,*$_exit sys exit .bss savr5: .=.+2 s. .globl _execv, cerror .comm __exectrap,2 rtt = 6 _execv: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 tst __exectrap beq 1f mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f jmp cerror .data 9: / C library-- fake floating output .globl pfloat .globl pscien pfloat: pscien: add $8,r4 movb $'?,(r3)+ rts pc : sys signal; 4; fptrap setd mov sp,r0 mov (r0),-(sp) tst (r0)+ mov r0,2(sp) jsr pc,_main cmp (sp)+,(sp)+ mov r0,(sp) jsr pc,*$_exit sys exit .bss savr5: .=.+2 s. .globl _execv, cerror .comm __exectrap,2 rtt = 6 _execv: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 tst __exectrap beq 1f mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f jmp cerror .data 9: / C library-- floating output .globl pfloat .globl pscien .globl fltused .globl _ndigit .globl ecvt .globl fcvt fltused: / force loading pfloat: mov r0,_ndigit tst r2 bne 1f mov $6,_ndigit 1: movf (r4)+,fr0 jsr pc,fcvt tst r1 beq 1f movb $'-,(r3)+ 1: tst r2 bgt 1f movb $'0,(r3)+ 1: mov r2,r1 ble 1f 2: movb (r0)+,(r3)+ sob r1,2b 1: mov _ndigit,r1 beq 1f movb $'.,(r3)+ 1: neg r2 ble 1f 2: dec r1 blt 1f movb $'0,(r3)+ sob r2,2b 1: tst r1 ble 2f 1: movb (r0)+,(r3)+ sob r1,1b 2:  rts pc pscien: mov r0,_ndigit tst r2 bne 1f mov $6,_ndigit 1: movf (r4)+,fr0 jsr pc,ecvt tst r1 beq 1f movb $'-,(r3)+ 1: movb (r0)+,(r3)+ movb $'.,(r3)+ mov _ndigit,r1 dec r1 ble 1f 2: movb (r0)+,(r3)+ sob r1,2b 1: movb $'e,(r3)+ dec r2 mov r2,r1 bge 1f movb $'-,(r3)+ neg r1 br 2f 1: movb $'+,(r3)+ 2: clr r0 div $10.,r0 add $'0,r0 movb r0,(r3)+ add $'0,r1 movb r1,(r3)+ rts pc 2: dec r1 blt 1f movb $'0,(r3)+ sob r2,2b 1: tst r1 ble 2f 1: movb (r0)+,(r3)+ sob r1,1b 2: / C library -- fork / pid = fork(); / / pid == 0 in child process; pid == -1 means error return .globl _fork, cerror _fork: mov r5,-(sp) mov sp,r5 sys fork br 1f bec 2f jmp cerror 1: clr r0 2: mov (sp)+,r5 rts pc 2b 1: movb $'e,(r3)+ dec r2 mov r2,r1 bge 1f movb $'-,(r3)+ neg r1 br 2f 1: movb $'+,(r3)+ 2: clr r0 div $10.,r0 add $'0,r0 movb r0,(r3)+ add $'0,r1 movb r1,(r3)+ rts pc 2: dec r1 blt 1f movb $'0,(r3)+ sob r2,2b 1: tst r1 ble 2f 1: movb (r0)+,(r3)+ sob r1,1b 2: / C library -- fstat / error = fstat(file, statbuf); / int statbuf[17] or / char statbuf[34] / as appropriate .globl _fstat, cerror _fstat: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys fstat; 0:.. r3)+ neg r1 br 2f 1: movb $'+,(r3)+ 2: clr r0 div $10.,r0 add $'0,r0 movb r0,(r3)+ add $'0,r1 movb r1,(r3)+ rts pc 2: dec r1 blt 1f movb $'0,(r3)+ sob r2,2b 1: tst r1 ble 2f 1: movb (r0)+,(r3)+ sob r1,1b 2: / C library -- exect / exect(file, argv); / / where argv is a vector argv[0] ... argv[x], 0 / last vector element must be 0 / / The same as execv except that it sets the TBIT causing / a trace trap on the first instruction of the executed instruction / to give a chance to set breakpoints. .globl _exect, cerror rtt = 6 _exect: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 mov $170000,-(sp) /in case it fails mov $cerror,-(sp) mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f rtt .data 9: sys exec; 0:..; .. xect(file, argv); / / where argv is a vector argv[0] ... argv[x], 0 / last vector element must be 0 / / The same as execv except that it sets the TBIT causing / a trace trap on the first instruction of the executed instruction / to give a chance to set breakpoints. .globl _exect, cerror rtt = 6 _exect: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 mov $170000,-(sp) /in case it fails mov $cerror,-(sp) mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f rtt .dat/ C Library - error logging functions / / errlog(0) Turn logging off / errlog(1) Turn logging on / .globl _errlog, cerror INDIR = 0 ELOG = 50. _errlog: mov r5,-(sp) mov sp,r5 mov 4(r5),func sys INDIR; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys ELOG; func:.. lobl _exect, cerror rtt = 6 _exect: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 mov $170000,-(sp) /in case it fails mov $cerror,-(sp) mov $170020,-(sp) / t-bit mov $1f,-(sp) rtt 1: sys 0; 9f rtt .dat/ getw/getc -- get words/characters from input file / fopen -- open a file for use by get(c|w) indir = 0 .globl _getc, _getw, _fopen .globl cerror .comm _errno,2 _fopen: mov r5,-(sp) mov sp,r5 mov 4(r5),0f sys 0; 9f .data 9: sys open; 0:..; 0 .text bes badret mov 6(r5),r1 mov r0,(r1)+ clr (r1)+ clr r0 mov (sp)+,r5 rts pc _getw: clr _errno mov r5,-(sp) mov sp,r5 mov 4(r5),r1 sub $2,2(r1) bge 1f cmp 2(r1),$-1 blt 2f movb *4(r1),-(sp) jsr pc,fill mov 4(r1),r0 br 3f 2: jsr pc,fill  dec 2(r1) 1: mov 4(r1),r0 movb (r0)+,-(sp) 3: movb (r0)+,1(sp) mov r0,4(r1) mov (sp)+,r0 mov (sp)+,r5 rts pc _getc: mov r5,-(sp) mov sp,r5 mov 4(r5),r1 dec 2(r1) bge 1f jsr pc,fill 1: clr r0 bisb *4(r1),r0 inc 4(r1) mov (sp)+,r5 rts pc fill: mov r1,r0 add $6,r0 mov r0,0f mov r0,4(r1) mov (r1),r0 sys 0; 9f .data 9: sys read; 0:..; 512. .text bes badret dec r0 bmi badret mov r0,2(r1) rts pc badret: jmp cerror ovb *4(r1),-(sp) jsr pc,fill mov 4(r1),r0 br 3f 2: jsr pc,fill / getchar() -- get a character from input file fin .globl _getchar .comm _errno,2 .comm _fin,518. _getchar: mov r5,-(sp) mov sp,r5 dec _fin+2 bge 1f mov $_fin+6,_fin+4 mov _fin,r0 sys read; _fin+6; 512. bes badret tst r0 beq badret dec r0 mov r0,_fin+2 1: clr r0 bisb *_fin+4,r0 inc _fin+4 mov (sp)+,r5 rts pc badret: mov r0,_errno clr r0 clr _fin+2 mov (sp)+,r5 rts pc badret mov r0,2(r1) rts pc badret: jmp cerror ovb *4(r1),-(sp) jsr pc,fill mov 4(r1),r0 br 3f 2: jsr pc,fill / C library - getcsw / csw = getcsw(); .globl _getcsw _getcsw: sys 38. rts pc .comm _fin,518. _getchar: mov r5,-(sp) mov sp,r5 dec _fin+2 bge 1f mov $_fin+6,_fin+4 mov _fin,r0 sys read; _fin+6; 512. bes badret tst r0 beq badret dec r0 mov r0,_fin+2 1: clr r0 bisb *_fin+4,r0 inc _fin+4 mov (sp)+,r5 rts pc badret: mov r0,_errno clr r0 clr _fin+2 mov (sp)+,r5 rts pc badret mov r0,2(r1) rts pc badret: jmp cerror ovb *4(r1),-(sp) jsr pc,fill mov 4(r1),r0 br 3f 2: jsr pc,fill / C library -- getgid / gid = getgid(); / getgid = 47. .globl _getgid _getgid: mov r5,-(sp) mov sp,r5 sys getgid mov (sp)+,r5 rts pc fin+2 bge 1f mov $_fin+6,_fin+4 mov _fin,r0 sys read; _fin+6; 512. bes badret tst r0 beq badret dec r0 mov r0,_fin+2 1: clr r0 bisb *_fin+4,r0 inc _fin+4 mov (sp)+,r5 rts pc badret: mov r0,_errno clr r0 clr _fin+2 mov (sp)+,r5 rts pc badret mov r0,2(r1) rts pc badret: jmp cerror ovb *4(r1),-(sp) jsr pc,fill mov 4(r1),r0 br 3f 2: jsr pc,fill / getpid -- get process ID getpid = 20. .globl _getpid .globl _getppid _getpid: sys getpid rts pc _getppid: sys getpid mov r1,r0 rts pc 2 bge 1f mov $_fin+6,_fin+4 mov _fin,r0 sys read; _fin+6; 512. bes badret tst r0 beq badret dec r0 mov r0,_fin+2 1: clr r0 bisb *_fin+4,r0 inc _fin+4 mov (sp)+,r5 rts pc badret: mov r0,_errno clr r0 clr _fin+2 mov (sp)+,r5 rts pc badret mov r0,2(r1) rts pc badret: jmp cerror ovb *4(r1),-(sp) jsr pc,fill mov 4(r1),r0 br 3f 2: jsr pc,fill getpw(uid, buf) int uid; char buf[]; { auto pbuf[259]; static pwf; register n, c; register char *bp; uid =& 0377; if(pwf == 0) { fopen("/etc/passwd", pbuf); pwf = pbuf[0]; } else pbuf[0] = pwf; if(pwf < 0) return(1); seek(pwf, 0, 0); pbuf[1] = 0; pbuf[2] = 0; for (;;) { bp = buf; while((c=getc(pbuf)) != '\n') { if(c <= 0) return(1); *bp++ = c; } *bp++ = '\0'; bp = buf; n = 3; while(--n) while((c = *bp++) != ':') if(c == '\n') return(1); while((c = *bp++) != ':') { if(c<'0' || c>'9') continue; n = n*10+c-'0'; } if(n == uid) return(0); } return(1); } if(pwf == 0) { fopen("/etc/passwd", pbuf); pwf = pbuf[0]; } else pbuf[0] = pwf; if(pwf < 0) return(1); seek(pwf, 0, 0); pbuf[1] = 0; pbuf[2] = 0; for (;;) { bp = buf; while((c=getc(pbuf)) != '\n') { if(c <= 0) return(1); *bp++ = c; } *bp++ = '\0'; bp = buf; n = 3; while(--n) while((c = *bp++) != ':') if(c == '\n') return(1); while((c = *bp/ C library -- getuid / uid = getuid(); / .globl _getuid _getuid: mov r5,-(sp) mov sp,r5 sys getuid mov (sp)+,r5 rts pc == 0) { fopen("/etc/passwd", pbuf); pwf = pbuf[0]; } else pbuf[0] = pwf; if(pwf < 0) return(1); seek(pwf, 0, 0); pbuf[1] = 0; pbuf[2] = 0; for (;;) { bp = buf; while((c=getc(pbuf)) != '\n') { if(c <= 0) return(1); *bp++ = c; } *bp++ = '\0'; bp = buf; n = 3; while(--n) while((c = *bp++) != ':') if(c == '\n') return(1); while((c = *bp/ C library -- gtty / error = gtty(filep, ttyvec); / filep is descriptor of open tty / ttyvec[0, 1, 2] correspond to args of gtty .globl _gtty, cerror _gtty: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys gtty; 0:.. while((c=getc(pbuf)) != '\n') { if(c <= 0) return(1); *bp++ = c; } *bp++ = '\0'; bp = buf; n = 3; while(--n) while((c = *bp++) != ':') if(c == '\n') return(1); while((c = *bp.globl _hmul _hmul: mov 2(sp),r0 mul 4(sp),r0 rts pc lep is descriptor of open tty / ttyvec[0, 1, 2] correspond to args of gtty .globl _gtty, cerror _gtty: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys gtty; 0:.. while((c=getc(pbuf)) != '\n') { if(c <= 0) return(1); *bp++ = c; } *bp++ = '\0'; bp = buf; n = 3; while(--n) while((c = *bp++) != ':') if(c == '\n') return(1); while((c = *bp/ C library -- latest version of hash switch .globl hsw mfpi = 6500^tst hsw: mov r0,r1 clr r0 mfpi (r2)+ div (sp)+,r0 asl r1 mfpi (r2)+ add (sp)+,r1 mov r0,*(r1)+ mov (r1)+,r1 1: cmp r0,-(r1) bne 1b rts r2 / jsr r2,nhswitch; magicdiv; tbase / jmp X-L0(r1) / /.data /tbase: / L0 / L1 / L2 / X / /L0: .. / V00 / V01 / V02 / V03 /L1: .. / V10 / V11 /L2: .. / V20 / V21 / V22 /L3: .. /X: / L00 / L01 / L02 / L03 / Ldef / L10 / L11 / Ldef / L20 / L21 / L22 / Ldef = '\n') return(1); while((c = *bp/ C library-- versions of long *, /, % for non-floating point hardware / also =* =% =/ .globl lmul, almul .globl csv, cret / / called:2(sp):LHS 6(sp):RHS lmul: jsr r5,csv mov 4.(r5),r2 mov 6.(r5),r3 clr r0 clr r1 mov $32.,r4 1: asl r1 rol r0 rol r3 rol r2 bcc 2f add 10.(r5),r1 adc r0 add 8.(r5),r0 2: sob r4,1b jmp cret / call is 2(sp):LHSptr 4(sp):RHS almul: jsr r5,csv mov 4.(r5),r3 mov (r3)+,r2 mov (r3)+,r3 clr r0 clr r1 mov $32.,r4 1: asl r1 rol r0 rol r3 rol r2 bcc 2f add 8.(r5),r1 adc r0 add 6.(r5),r0 2: sob r4,1b mov 4.(r5),r3 mov r0,(r3)+ mov r1,(r3)+ jmp cret .globl ldiv .globl lrem / Both called 2(sp):LHS 6(sp):RHS lrem: jsr r5,csv mov $100,-(sp) br 1f ldiv: jsr r5,csv clr -(sp) 1: mov 6.(r5),r3 mov 4.(r5),r2 bpl 1f inc (sp) neg r2 neg r3 sbc r2 1: clr r0 clr r1 tst 8.(r5) bge 1f neg 8.(r5) neg 10.(r5) sbc 8.(r5) inc (sp) 1: mov $32.,r4 1: ashc $1,r2 rol r1 rol r0 cmp 8.(r5),r0 blt 2f bgt 3f cmp 10.(r5),r1 blos 2f 3: sob r4,1b br 1f 2: sub 10.(r5),r1 sbc r0 sub 8.(r5),r0 inc r3 sob r4,1b 1: bit $100,(sp) beq 3f tst 4.(r5) bpl 1f br 2f 3: mov r2,r0 mov r3,r1 bit $1,(sp)+ beq 1f 2: neg r0 neg r1 sbc r0 1: jmp cret .globl alrem, aldiv / Called 2(sp):LHSptr 4(sp):RHS alrem: jsr r5,csv mov $100,-(sp) br 1f aldiv: jsr r5,csv clr -(sp) 1: mov 4.(r5),r2 mov 2(r2),r3 mov (r2),r2 bpl 1f inc (sp) neg r2 neg r3 sbc r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mov $32.,r4 1: ashc $1,r2 rol r1 rol r0 cmp 6.(r5),r0 blt 2f bgt 3f cmp 8.(r5),r1 blos 2f 3: sob r4,1b br 1f 2: sub 8.(r5),r1 sbc r0 sub 6.(r5),r0 inc r3 sob r4,1b 1: mov 4(r5),r4 bit $100,(sp) beq 3f tst (r4) bpl 1f br 2f 3: mov r2,r0 mov r3,r1 bit $1,(sp)+ beq 1f 2: neg r0 neg r1 sbc r0 1: mov r0,(r4)+ mov r1,(r4) jmp cret 2(r2),r3 mov (r2),r2 bpl 1f inc (sp) neg r2 neg r3 sbc r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mo/ / Convert pair of integers to a long / .globl _itol _itol: mov 2(sp),r0 mov 4(sp),r1 rts pc sob r4,1b br 1f 2: sub 8.(r5),r1 sbc r0 sub 6.(r5),r0 inc r3 sob r4,1b 1: mov 4(r5),r4 bit $100,(sp) beq 3f tst (r4) bpl 1f br 2f 3: mov r2,r0 mov r3,r1 bit $1,(sp)+ beq 1f 2: neg r0 neg r1 sbc r0 1: mov r0,(r4)+ mov r1,(r4) jmp cret 2(r2),r3 mov (r2),r2 bpl 1f inc (sp) neg r2 neg r3 sbc r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mo/ C library -- kill .globl _kill, cerror kill = 37. indir = 0 _kill: mov r5,-(sp) mov sp,r5 mov 4(sp),r0 mov 6(sp),8f sys indir; 9f .data 9: sys kill; 8:.. .text bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc 4) bpl 1f br 2f 3: mov r2,r0 mov r3,r1 bit $1,(sp)+ beq 1f 2: neg r0 neg r1 sbc r0 1: mov r0,(r4)+ mov r1,(r4) jmp cret 2(r2),r3 mov (r2),r2 bpl 1f inc (sp) neg r2 neg r3 sbc r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mo/ C routine-- long integer subtract and add .globl _lsub .globl _ladd .globl csv .globl cret _lsub: jsr r5,csv mov 6(r5),r2 mov (r2)+,r0 mov (r2),r1 mov 10(r5),r2 sub (r2)+,r0 sub (r2),r1 sbc r0 mov 4(r5),r2 mov r0,(r2)+ mov r1,(r2) jmp cret _ladd: jsr r5,csv mov 6(r5),r2 mov (r2)+,r0 mov (r2),r1 mov 10(r5),r2 add (r2)+,r0 add (r2),r1 adc r0 mov 4(r5),r2 mov r0,(r2)+ mov r1,(r2) jmp cret r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mocall = 57. / C library -- lcall / lcall(file, arg1, arg2, ... , 0); / .globl _lcall, cerror _lcall: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov r5,r0 add $6,r0 mov r0,0f+2 sys 0; 9f br 1f 1: bec 2f jmp cerror 2: mov (sp)+,r5 rts pc .data 9: sys call; 0:..; .. csv mov 6(r5),r2 mov (r2)+,r0 mov (r2),r1 mov 10(r5),r2 add (r2)+,r0 add (r2),r1 adc r0 mov 4(r5),r2 mov r0,(r2)+ mov r1,(r2) jmp cret r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: moldfps = 170100^tst / / ldfps(number); .globl _ldfps _ldfps: ldfps 2(sp) rts pc all, cerror _lcall: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov r5,r0 add $6,r0 mov r0,0f+2 sys 0; 9f br 1f 1: bec 2f jmp cerror 2: mov (sp)+,r5 rts pc .data 9: sys call; 0:..; .. csv mov 6(r5),r2 mov (r2)+,r0 mov (r2),r1 mov 10(r5),r2 add (r2)+,r0 add (r2),r1 adc r0 mov 4(r5),r2 mov r0,(r2)+ mov r1,(r2) jmp cret r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mo/ C library -- link / error = link(old-file, new-file); / .globl _link, cerror _link: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys link; 0:..; .. ts pc .data 9: sys call; 0:..; .. csv mov 6(r5),r2 mov (r2)+,r0 mov (r2),r1 mov 10(r5),r2 add (r2)+,r0 add (r2),r1 adc r0 mov 4(r5),r2 mov r0,(r2)+ mov r1,(r2) jmp cret r2 1: clr r0 clr r1 tst 6.(r5) bge 1f neg 6.(r5) neg 8.(r5) sbc 6.(r5) inc (sp) 1: mo/ c library - semaphore functions / / allocsem(number, usage) / freesem(number) / / lock(number) / unlock(number) / tlock(number) / / p(number) / v(number) / test(number) / .globl _allocsem, _freesem .globl _lock, _unlock, _tlock .globl _p, _v, _test .globl cerror INDIR = 0 SEMI4 = 62. NLOCKS = 10. TBLSZ = [NLOCKS + 7] \/ 8. EINVAL = 22. PV = 3 LOCK = 0 UNLOCK = 1 TLOCK = 2 P = 3 V = 4 TEST = 5 ALLOC = 6 FREE = 7 .text _lock: movb $LOCK,desire br 1f _unlock: movb $UNLOCK,desire br 1f _tlock: movb $TLOCK,desire br 1f _p: movb $P,desire br 1f _v: movb $V,desire br 1f _test: movb $TEST,desire 1: mov r5,-(sp) mov sp,r5 mov 4(r5),flag bge 1f mov $EINVAL,r0 /neg semi4 numbers bad jmp cerror 1: jsr pc,mposit bitb mapmsk,*mapadd /already allocated? bne 2f mov $ALLOC,func cmpb $P,desire bhi 1f movb $PV,func+1 1: sys INDIR; 9f bec 1f jmp cerror 1: bisb mapmsk,*mapadd 2: clr func movb desire,func sys INDIR; 9f bec 1f jmp cerror 1: mov (sp)+,r5 rts pc _allocsem: mov r5,-(sp) mov sp,r5 mov $ALLOC,func movb 6(r5),func+1 mov 4(r5),flag sys INDIR; 9f bec 1f jmp cerror 1: mov r0,flag jsr pc,mposit bisb mapmsk,*mapadd mov flag,r0 mov (sp)+,r5 rts pc _freesem: mov r5,-(sp) mov sp,r5 mov $FREE,func mov 4(r5),flag bmi 1f jsr pc,mposit bicb mapmsk,*mapadd br 2f 1: mov $[TBLSZ-1],r0 1: clrb bmap(r0) dec r0 bge 1b 2: sys INDIR; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc mposit: / find bit map position cmp $NLOCKS,flag bhi 1f movb $1,mapmsk /out of range...response mov $mapmsk,mapadd /will never fail rts pc 1: mov flag,r0 mov r0,r1 ash $-3,r1 add $bmap,r1 mov r1,mapadd mov $1,r1 bic $!7,r0 ash r0,r1 movb r1,mapmsk rts pc .data 9: sys SEMI4; func:..; flag:.. mapadd: .. mapmsk: .byte 0 desire: .byte 0 bmap: . = . + TBLSZ r 2f 1: mov $[TBLSZ-1],r0 1: clrb bmap(r0) dec r0 bge 1b 2: sys INDIR; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc mposit: / find bit map position cmp $NLOCKS,flag bhi 1f movb $1,mapmsk /out/ C library -- long output conversion .globl _locv _locv: mov r5,-(sp) mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) mov $buf,r4 mov 6(r5),r3 mov 4(r5),r2 bpl 1f neg r2 neg r3 sbc r2 movb $'-,(r4)+ 1: jsr pc,1f clrb (r4)+ mov $buf,r0 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 mov (sp)+,r5 rts pc 1: jsr pc,divid add $'0,r1 mov r1,-(sp) ashc $0,r2 beq 1f jsr pc,1b 1: movb (sp)+,(r4)+ rts pc divid: clr r1 mov $32.,r0 1: ashc $1,r2 rol r1 cmp r1,$10. blo 2f sub $10.,r1 inc r3 2: sob r0,1b rts pc .bss buf: .=.+12. locv _locv: mov r5,-(sp) mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) mov $buf,r4 mov 6(r5),r3 mov 4(r5),r2 bpl 1f neg r2 neg r3 sbc r2 movb $'-,(r4)+ 1: jsr pc,1f clrb (r4)+ mov $buf,r0 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 mov (sp)+,r5 rts pc 1: jsr pc,divid add $'0,r1 mov r1,-(sp) ashc $0,r2 beq 1f jsr pc,1b 1: movb (sp)+,(r4)+ rts pc divid: clr r1 mov $32.,r0 1: ashc $1,r2 rol r1 cmp r1,$10. blo 2f sub $10.,r1 in/ C library-- versions of long *, /, % for floating point hardware / also =* =% =/ .globl lmul, ldiv, lrem, almul, aldiv, alrem .globl fptrap / / called: 2(sp):LHS 6(sp):RHS lmul: setl movif 2(sp),r0 movif 6(sp),r1 mulf r1,r0 movfi r0,-(sp) mov (sp)+,r0 mov (sp)+,r1 seti rts pc ldiv: setl movif 2(sp),r0 movif 6(sp),r1 divf r1,r0 movfi r0,-(sp) mov (sp)+,r0 mov (sp)+,r1 seti rts pc lrem: setl movif 2(sp),r0 movf r0,r2 movif 6(sp),r1 movf r1,r3 divf r1,r0 modf $40200,r0 mulf r3,r1 subf r1,r2 movfi r2,-(sp) mov (sp)+,r0 mov (sp)+,r1 seti rts pc / / called: 2(sp):ptr to LHS 4(sp):RHS almul: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 mulf fr1,fr0 movfi fr0,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc aldiv: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 divf fr1,fr0 movfi fr0,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc alrem: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 movf fr0,fr2 movf fr1,fr3 divf fr1,fr0 modf $40200,fr0 mulf fr3,fr1 subf fr1,fr2 movfi fr2,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc pc / / called: 2(sp):ptr to LHS 4(sp):RHS almul: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 mulf fr1,fr0 movfi fr0,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc aldiv: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 divf fr1,fr0 movfi fr0,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc alrem: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 movf fr0,fr2 movf fr1,fr3 divf fr1,fr0 modf $40200,fr0 mulf fr3,fr1 / C library -- return floating-point from long integer .globl _ltod _ltod: mov r5,-(sp) mov sp,r5 setl movif *4(r5),fr0 seti mov (sp)+,r5 rts pc / return long integer from floating / dtol(d, l) .globl _dtol _dtol: mov r5,-(sp) mov sp,r5 setl movf 4(r5),fr0 movfi fr0,*12.(r5) seti mov (sp)+,r5 rts pc movfi fr0,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc alrem: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 movf fr0,fr2 movf fr1,fr3 divf fr1,fr0 modf $40200,fr0 mulf fr3,fr1 / / ltoi(long) returns the l.s. part of the long as an int. .globl _ltoi _ltoi: mov 6(sp),r0 rts pc etl movif *4(r5),fr0 seti mov (sp)+,r5 rts pc / return long integer from floating / dtol(d, l) .globl _dtol _dtol: mov r5,-(sp) mov sp,r5 setl movf 4(r5),fr0 movfi fr0,*12.(r5) seti mov (sp)+,r5 rts pc movfi fr0,(r0) mov 2(r0),r1 mov (r0),r0 seti rts pc alrem: setl mov 2(sp),r0 movif (r0),fr0 movif 4(sp),fr1 movf fr0,fr2 movf fr1,fr3 divf fr1,fr0 modf $40200,fr0 mulf fr3,fr1 / C library -- ioctl / error = ioctl(filep, command|(device<<8), arg2); / filep is descriptor of open character device / command specifies ioctl operation / device is a character identifying type of device (ex 't' for tty) / arg2 is argument for specified command and may be a pointer / to a string of arguments ioctl = 54. .globl _ioctl, cerror _ioctl: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f mov 8(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys ioctl; 0:..; .. ry -- ioctl / error = ioctl(filep, command|(device<<8), arg2); / filep is descriptor of open character device / command specifies ioctl operation / device is a character identifying type of device (ex 't' for tty) / arg2 is argument for specified command and may be a pointer / to a string of arguments ioctl = 54. .globl _ioctl, cerror _ioctl: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f mov 8(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys ioctl; lseek(f, o0, o1, p) { register r; if((o0 == 0 && o1 >= 0) || (o0 == -1 && o1 < 0)) return(seek(f, o1, p)); if(p > 2) return(-1); r = (o0<<7) | ((o1>>9)&0177); if(seek(f, r, p+3) < 0) return(-1); return(seek(f, o1&0777, 1)); } ment for specified command and may be a pointer / to a string of arguments ioctl = 54. .globl _ioctl, cerror _ioctl: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f mov 8(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys ioctl; / count subroutine calls during profiling .globl mcount .comm countbase,2 mcount: mov (r0),r1 bne 1f mov countbase,r1 beq 2f add $6,countbase mov (sp),(r1)+ mov r1,(r0) 1: inc 2(r1) bne 2f inc (r1) 2: rts pc o1&0777, 1)); } ment for specified command and may be a pointer / to a string of arguments ioctl = 54. .globl _ioctl, cerror _ioctl: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f mov 8(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys ioctl; / C runtime startoff including monitoring cbufs = 150. .globl _monitor .globl _sbrk .globl _main .globl _exit .globl _IEH3exit .globl _etext .comm countbase,2 .comm savr5,2 start: setd mov sp,r0 mov (r0),-(sp) tst (r0)+ mov r0,2(sp) mov $_etext,r1 sub $eprol,r1 add $7,r1 ash $-3,r1 bic $!17777,r1 mov $cbufs,-(sp) add $3*[cbufs+1],r1 mov r1,-(sp) asl r1 mov r1,-(sp) jsr pc,_sbrk tst (sp)+ cmp r0,$-1 beq 9f mov r0,-(sp) add $6,r0 mov r0,countbase mov $_etext,-(sp) mov $eprol,-(sp) jsr pc,_monitor add $10.,sp jsr pc,_main cmp (sp)+,(sp)+ jsr pc,_exit 9: mov $2,r0 sys write; 8f; 9f-8f .data; 8: ; 9:.even; .text _exit: _IEH3exit: mov r5,-(sp) mov sp,r5 clr -(sp) jsr pc,_monitor tst (sp)+ mov 4(r5),r0 sys exit eprol: ash $-3,r1 bic $!17777,r1 mov $cbufs,-(sp) add $3*[cbufs+1],r1 mov r1,-(sp) asl r1 mov r1,-(sp) jsr pc,_sbrk tst (sp)+ cmp r0,$-1 beq 9f mov r0,-(sp) add $6,r0 mov r0,countbase mov $_etext,-(sp) mov $eprol,-(sp)/ C library -- mknod / error = mknod(string, mode, major.minor); .globl _mknod, cerror mknod = 14. _mknod: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 mov 8(r5),0f+4 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys mknod; 0:..; ..; .. eprol: ash $-3,r1 bic $!17777,r1 mov $cbufs,-(sp) add $3*[cbufs+1],r1 mov r1,-(sp) asl r1 mov r1,-(sp) jsr pc,_sbrk tst (sp)+ cmp r0,$-1 beq 9f mov r0,-(sp) add $6,r0 mov r0,countbase mov $_etext,-(sp) mov $eprol,-(sp)mktemp(as) char *as; { register char *s; register pid, i; int sign; int sbuf[20]; pid = getpid(); sign = 0; while (pid<0) { pid =- 10000; sign++; } s = as; while (*s++); s--; i = 0; while (*--s == 'X') { *s = (pid%10) + '0'; pid =/ 10; if (++i == 5) *s =+ sign; } s =+ i; while (stat(as, sbuf) != -1) { if (i==0 || sign>=20) return("/"); *s = 'a' + sign++; } return(as); } cmp r0,$-1 beq 9f mov r0,-(sp) add $6,r0 mov r0,countbase mov $_etext,-(sp) mov $eprol,-(sp)monitor(lowpc, highpc, buf, bufsiz, cntsiz) char *lowpc, *highpc; int *buf, bufsiz; { register char *o; static *sbuf, ssiz; if (lowpc == 0) { profil(0, 0, 0, 0); o = creat("mon.out", 0666); write(o, sbuf, ssiz<<1); close(o); return; } if (nargs() <= 4) cntsiz = 0; ssiz = bufsiz; buf[0] = lowpc; buf[1] = highpc; buf[2] = cntsiz; sbuf = buf; buf =+ 3*(cntsiz+1); bufsiz =- 3*(cntsiz+1); if (bufsiz<=0) return; o = ((highpc - lowpc)>>1) & 077777; if(bufsiz < o) o = ldiv(bufsiz, 0, o<<1); else o = 077777; profil(buf, bufsiz<<1, lowpc, o<<1); } nt *buf, bufsiz; { register char *o; static *sbuf, ssiz; if (lowpc == 0) { profil(0, 0, 0, 0); o = creat("mon.out", 0666); write(o, sbuf, ssiz<<1); close(o); return; } if (nargs() <= 4) cntsiz = 0; ssiz = bufsiz; buf[0] = lowpc; buf[1] = highpc; buf[2] = cntsiz; sbuf = buf; buf =+ 3*(cntsiz+1); bufsiz =- 3*(cntsiz+1); if (bufsiz<=0) return; o = ((highpc - lowpc)>>1) & 077777; if(bufsiz < o) o = ldiv(bufsiz, 0,/ C library -- mount / error = mount(dev, file, flag) .globl _mount, cerror _mount: mov r5,-(sp) mov sp,r5 mov 4(sp),0f mov 6(sp),0f+2 mov 8(sp),0f+4 sys 0; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc .data 9: sys mount; 0:..; ..; .. args() <= 4) cntsiz = 0; ssiz = bufsiz; buf[0] = lowpc; buf[1] = highpc; buf[2] = cntsiz; sbuf = buf; buf =+ 3*(cntsiz+1); bufsiz =- 3*(cntsiz+1); if (bufsiz<=0) return; o = ((highpc - lowpc)>>1) & 077777; if(bufsiz < o) o = ldiv(bufsiz, 0,/ c library - message functions / / msgenab() / msgdisab() / / send(buffer,size,topid,type) conditional send / sendw(buffer,size,topid,type) unconditional send / / recv(buffer,size,&structure,type) conditional receive / recvw(buffer,size,&structure,type) unconditional receive / .globl _msgenab,_msgdisab .globl _send,_sendw .globl _recv,_recvw .globl cerror INDIR = 0 MSG = 49. DISAB = 0 ENAB = 1 SEND = 2 SENDW = 3 RECV = 4 RECVW = 5 .text _msgdisab: mov $DISAB,func br 1f _msgenab: mov $ENAB,func 1:  mov r5,-(sp) mov sp,r5 sys INDIR; 9f bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc _send: mov $SEND,func br 1f _sendw: mov $SENDW,func br 1f _recv: mov $RECV,func br 1f _recvw: mov $RECVW,func 1: mov r5,-(sp) mov sp,r5 mov 4(r5),buf mov 6(r5),r0 mov 8.(r5),arg3 mov 10.(r5),type sys INDIR; 9f bec 1f jmp cerror 1: mov (sp)+,r5 rts pc .data 9: sys MSG; func:..; buf:..; arg3:..; type:.. RECV = 4 RECVW = 5 .text _msgdisab: mov $DISAB,func br 1f _msgenab: mov $ENAB,func 1: / C library -- nargs .globl _nargs _nargs: mov r5,-(sp) mov 2(r5),r1 / pc of caller of caller mov sp,r5 clr r0 cmp -4(r1),jsrsd bne 8f mov $2,r0 8: cmp (r1),tsti bne 1f add $2,r0 br 2f 1: cmp (r1),cmpi bne 1f add $4,r0 br 2f 1: cmp (r1),addi bne 1f add 2(r1),r0 br 2f 1: cmp (r1),jmpi bne 1f add 2(r1),r1 add $4,r1 br 8b 1: cmpb 1(r1),bri+1 bne 2f mov r0,-(sp) mov (r1),r0 swab r0 ash $-7,r0 add r0,r1 add $2,r1 mov (sp)+,r0 br 8b 2: asr r0 mov (sp)+,r5 rts pc .data jsrsd: jsr pc,*$0 tsti: tst (sp)+ cmpi: cmp (sp)+,(sp)+ addi: add $0,sp jmpi: jmp 0 bri: br . f caller mov sp,r5 clr r0 cmp -4(r1),jsrsd bne 8f mov $2,r0 8: cmp (r1),tsti bne 1f add $2,r0 br 2f 1: cmp (r1),cmpi bne 1f add $4,r0 br 2f 1: cmp (r1),addi bne 1f add 2(r1),r0 br 2f 1: cmp (r1),jmpi bne 1f add 2(r1),r1 add $4,r1 br 8b 1: cmpb 1(r1),bri+1 bne 2f mov r0,-(sp) mov (r1),r0 swab r0 ash $-7,r0 add r0,r1 add $2,r1 mov (sp)+,r0 br 8b 2: asr r0 mov (sp)+,r5 rts pc .data jsrsrin() { register n, c, f; f = 1; n = 0; loop: c = getchar(); if(c == '\0') exit(); if(c == '-') { f = -f; goto loop; } if(c>='0' && c<='9') { n = n*10+c-'0'; goto loop; } return(n*f); } (r1),cmpi bne 1f add $4,r0 br 2f 1: cmp (r1),addi bne 1f add 2(r1),r0 br 2f 1: cmp (r1),jmpi bne 1f add 2(r1),r1 add $4,r1 br 8b 1: cmpb 1(r1),bri+1 bne 2f mov r0,-(sp) mov (r1),r0 swab r0 ash $-7,r0 add r0,r1 add $2,r1 mov (sp)+,r0 br 8b 2: asr r0 mov (sp)+,r5 rts pc .data jsrs/ C library-- nice / error = nice(hownice) .globl _nice, cerror _nice: mov r5,-(sp) mov sp,r5 mov 4(sp),r0 sys nice bec 1f jmp cerror 1: clr r0 mov (sp)+,r5 rts pc goto loop; } return(n*f); } (r1),cmpi bne 1f add $4,r0 br 2f 1: cmp (r1),addi bne 1f add 2(r1),r0 br 2f 1: cmp (r1),jmpi bne 1f add 2(r1),r1 add $4,r1 br 8b 1: cmpb 1(r1),bri+1 bne 2f mov r0,-(sp) mov (r1),r0 swab r0 ash $-7,r0 add r0,r1 add $2,r1 mov (sp)+,r0 br 8b 2: asr r0 mov (sp)+,r5 rts pc .data jsrsstruct nlist { int name[4]; /* really char[8] */ int type; int value; }; nlist(name, list) char *name; struct nlist *list; { register struct nlist *p, *q; int f, n, m; long lng; long itol(); int buf[010]; struct nlist space[100]; for(p = list; p->name[0]; p++) { p->type = -1; p->value = 0; } f = open(name, 0); if(f < 0) return(-1); read(f, buf, sizeof buf); n = buf[0]; if((n != 0407 && n != 0410 && n != 0411 && n != 0405) || buf[4]==0) { close(f); return(-1); } lng = itol(0, buf[1]); lng =+ itol(0, buf[2]); if(buf[7] != 1) lng = lng << 1; lng =+ 020; lseek(f, lng, 0); n = buf[4]; loop: if(n == 0) { close(f); return(0); } m = 1200; if(n < 1200) m = n; read(f, space, m); n =- m; for(q = space; (m =- 12) >= 0; q++) { for(p = list; p->name[0]; p++) { if(p->name[0] != q->name[0]) continue; if(p->name[1] != q->name[1]) continue; if(p->name[2] != q->name[2]) continue; if(p->name[3] != q->name[3]) continue; p->value = q->value; p->type = q->type; break; } } goto loop; } ) lng = lng << 1; lng =+ 020; lseek(f, lng, 0); n = buf[4]; loop: if(n == 0) { close(f); return(0); } m = 1200; if(n < 1200) m = n; read(f, space, m); n =- m; for(q = space; (m =- 12) >= 0; q++) { for(p = list; p->name[0]; p++) { if(p->name[0] != q->name[0]) continue; if(p->name[1] != q->name[1]) continue; if(p->name[2] != q->name[2]) continue; if(p->name[3] != q->name[3]) continue; p->value = q->value; p->/ C library -- open / file = open(string, mode) / / file == -1 means error .globl _open, cerror _open: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: mov (sp)+,r5 rts pc .data 9: sys open; 0:..; .. 12) >= 0; q++) { for(p = list; p->name[0]; p++) { if(p->name[0] != q->name[0]) continue; if(p->name[1] != q->name[1]) continue; if(p->name[2] != q->name[2]) continue; if(p->name[3] != q->name[3]) continue; p->value = q->value; p->/* * Print the error indicated * in the cerror cell. */ int errno; int sys_nerr; char *sys_errlist[]; perror(s) char *s; { register char *c; register n; c = "Unknown error"; if(errno < sys_nerr) c = sys_errlist[errno]; n = strlen(s); if(n) { write(2, s, n); write(2, ": ", 2); } write(2, c, strlen(c)); write(2, "\n", 1); } /* * Return the number of bytes in a string */ strlen(str) char *str; { register char *s; s = str; while(*s++) ; return(s-str-1); } >value = q->value; p->/ pipe -- C library / pipe(f) / int f[2]; .globl _pipe, cerror, csv, cret pipe = 42. _pipe: jsr r5,csv sys pipe bec 1f jmp cerror 1: mov 4(r5),r2 mov r0,(r2)+ mov r1,(r2) clr r0 jmp cret rr) c = sys_errlist[errno]; n = strlen(s); if(n) { write(2, s, n); write(2, ": ", 2); } write(2, c, strlen(c)); write(2, "\n", 1); } /* * Return the number of bytes in a string */ strlen(str) char *str; { register char *s; s = str; while(*s++) ; return(s-str-1); } >value = q->value; p->/ C library -- printf .globl _printf .globl pfloat .globl pscien .globl _putchar .globl csv .globl cret _printf: jsr r5,csv sub $126.,sp mov 4(r5),formp / format mov r5,r4 add $6,r4 / arglist loop: movb *formp,r0 beq 1f inc formp cmp r0,$'% beq 2f 3: mov r0,(sp) jsr pc,*$_putchar br loop 1: jmp cret 2: clr rjust clr ndigit cmpb *formp,$'- bne 2f inc formp inc rjust 2: jsr r3,gnum mov r1,width clr ndfnd cmp r0,$'. bne 1f jsr r3,gnum mov r1,ndigit 1: mov sp,r3 add $4,r3 mov $swtab,r1 1: mov (r1)+,r2 beq 3b cmp r0,(r1)+ bne 1b jmp (r2) .data swtab: decimal; 'd octal; 'o hex; 'x float; 'f scien; 'e charac; 'c string; 's longorunsg; 'l unsigned; 'u remote; 'r long; 'D loct; 'O lhex; 'X 0; 0 .text decimal: mov (r4)+,r1 bge 1f neg r1 movb $'-,(r3)+ br 1f longorunsg: movb *formp,r0 inc formp cmp r0,$'o beq loct cmp r0,$'x beq lhex cmp r0,$'d beq long dec formp br unsigned unsigned: mov (r4)+,r1 1: jsr pc,1f jmp prbuf 1: clr r0 div $10.,r0 mov r1,-(sp) mov r0,r1 beq 1f jsr pc,1b 1: mov (sp)+,r0 add $'0,r0 movb r0,(r3)+ rts pc long: mov (r4)+,r2 mov (r4)+,r0 mov r4,-(sp) mov r3,r4 mov r0,r3 tst r2 bpl 1f neg r2 neg r3 sbc r2 movb $'-,(r4)+ 1: jsr pc,1f mov r4,r3 mov (sp)+,r4 br prbuf 1: clr r1 mov $32.,r0 3: ashc $1,r2 rol r1 cmp r1,$10. blo 2f sub $10.,r1 inc r3 2: sob r0,3b add $'0,r1 mov r1,-(sp) ashc $0,r2 beq 1f jsr pc,1b 1: movb (sp)+,(r4)+ rts pc charac: movb (r4)+,(r3)+ bne 1f  dec r3 1: movb (r4)+,(r3)+ bne prbuf dec r3 br prbuf string: mov ndigit,r1 clr r3 mov (r4),r2 bne 1f mov $nulstr,r2 mov r2,(r4) 1: tstb (r2)+ beq 1f inc r3 sob r1,1b 1: mov (r4)+,r2 br prstr lhex: mov (r4)+,r0 br 1f hex: clr r0 1: mov $1f,r2 .data 1: -4; !17; 170000 .text br 2f loct: mov (r4)+,r0 br 1f octal: clr r0 1: mov $1f,r2 .data 1: -3; !7; 160000 .text 2: mov (r4)+,r1 ashc $0,r0 beq 2f tst ndigit beq 2f movb $'0,(r3)+ 2: jsr pc,1f br prbuf 1: mov r1,-(sp) ashc (r2),r0 bic 4(r2),r0 ashc $0,r0 beq 1f jsr pc,1b 1: mov (sp)+,r0 bic 2(r2),r0 add $'0,r0 cmp r0,$'9 ble 1f add $'A-'0-10.,r0 1: movb r0,(r3)+ rts pc float: mov ndigit,r0 mov ndfnd,r2 jsr pc,pfloat br prbuf scien: mov ndigit,r0 mov ndfnd,r2 jsr pc,pscien br prbuf remote: mov (r4)+,r4 mov (r4)+,formp jmp loop prbuf: mov sp,r2 add $4,r2 sub r2,r3 prstr: mov r4,-(sp) mov $' ,-(sp) mov r3,r4 neg r3 add width,r3 ble 1f tst rjust bne 1f 2: jsr pc,*$_putchar sob r3,2b 1: tst r4 beq 2f 1: movb (r2)+,(sp) jsr pc,*$_putchar sob r4,1b 2: tst r3 ble 1f mov $' ,(sp) 2: jsr pc,*$_putchar sob r3,2b 1: tst (sp)+ mov (sp)+,r4 jmp loop gnum: clr ndfnd clr r1 1: movb *formp,r0 inc formp sub $'0,r0 cmp r0,$'*-'0 bne 2f mov (r4)+,r0 br 3f 2: cmp r0,$9. bhi 1f 3: inc ndfnd mul $10.,r1 add r0,r1 br 1b 1: add $'0,r0 rts r3 .bss width: .=.+2 formp: .=.+2 rjust: .=.+2 ndfnd: .=.+2 ndigit: .=.+2 .data nulstr: <(null)\0> e 1f 2: jsr pc,*$_putchar sob r3,2b 1:/ profil .globl _profil _profil: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),0f+2 mov 10(r5),0f+4 mov 12(r5),0f+6 sys 0; 9f mov (sp)+,r5 rts pc .data 9: sys 44.; 0:..; ..; ..; .. r r1 1: movb *formp,r0 inc formp sub $'0,r0 cmp r0,$'*-'0 bne 2f mov (r4)+,r0 br 3f 2: cmp r0,$9. bhi 1f 3: inc ndfnd mul $10.,r1 add r0,r1 br 1b 1: add $'0,r0 rts r3 .bss width: .=.+2 formp: .=.+2 rjust: .=.+2 ndfnd: .=.+2 ndigit: .=.+2 .data nulstr: <(null)\0> e 1f 2: jsr pc,*$_putchar sob r3,2b 1:/ ptrace -- C library / result = ptrace(req, pid, addr, data); ptrace = 26. indir = 0 .globl _ptrace .globl cerror, _errno _ptrace: mov r5,-(sp) mov sp,r5 mov 4.(r5),0f+4 mov 6.(r5),0f+0 mov 8.(r5),0f+2 mov 10.(r5),r0 clr _errno sys indir; 9f bec 1f jmp cerror 1: mov (sp)+,r5 rts pc .data 9: sys ptrace; 0: .=.+6 add r0,r1 br 1b 1: add $'0,r0 rts r3 .bss width: .=.+2 formp: .=.+2 rjust: .=.+2 ndfnd: .=.+2 ndigit: .=.+2 .data nulstr: <(null)\0> e 1f 2: jsr pc,*$_putchar sob r3,2b 1:/ putw/putc -- write words/characters on output file .globl _putc, _putw, _fflush, _fcreat .globl cerror .comm _errno,2 _fcreat: mov r5,-(sp) mov sp,r5 mov 4(r5),0f mov 6(r5),r1 mov pc,(r1) / a putatively illegal file desc. sys 0; 9f .data 9: sys creat; 0:..; 666 .text bes badret mov r0,(r1)+ clr (r1)+ clr (r1)+ br goodret _putw: mov r5,-(sp) mov sp,r5 mov 6(r5),r1 dec 2(r1) bge 1f jsr pc,fl dec 2(r1) 1: movb 4(r5),*4(r1) inc 4(r1) dec 2(r1) bge 1f jsr pc,fl dec 2(r1) 1: movb 5(r5),*4(r1) inc 4(r1) mov 4(r5),r0 br goodret _putc: mov r5,-(sp) mov sp,r5 mov 6(r5),r1 dec 2(r1) bge 1f jsr pc,fl dec 2(r1) 1: mov 4(r5),r0 movb r0,*4(r1) inc 4(r1) br goodret _fflush: mov r5,-(sp) mov sp,r5 mov 4(r5),r1 jsr pc,fl br goodret fl: mov r1,r0 add $6,r0 mov r0,-(sp) mov r0,0f mov 4(r1),0f+2 beq 1f sub r0,0f+2 mov (r1),r0 sys 0; 9f .data 9: sys write; 0:..; .. .text 1: mov (sp)+,4(r1) mov $512.,2(r1) rts pc badret: jmp cerror goodret: clr _errno mov (sp)+,r5 rts pc inc 4(r1) mov 4(r5),r0 br goodret _putc: mov r5,-(sp) mov sp,r5 mov 6(r5),r1 dec 2(r1) bge 1f jsr pc,fl dec 2(r1) 1: mov 4(r5),r0 movb r0,*4(r1) inc 4(r1) br goodret _fflush: mov r5,-(sp) mov sp,r5 mov 4(r5),r1 jsr pc,fl br goodret fl: mov r1,r0 add $6,r0 mov r0,-(sp) mov r0,0f mov 4(r1),0f+2 beq 1f sub r0,0f+2 mov (r1),r0 sys 0; 9f .data 9: sys write; 0:..; .. .text 1: mov (sp)+,4(r1) mov $512.,2(r1) rts pc badret: jmp cerror goodret: clr _errno mov (sp)/ C library -- putchar .globl _putchar,_flush .globl _fout _putchar: mov r5,-(sp) mov sp,r5 mov _fout+4,r0 bne 1f jsr pc,fl mov _fout+4,r0 1: movb 4(r5),(r0)+ beq 1f inc _fout+4 dec _fout+2 bgt 1f jsr pc,fl 1: mov 4(r5),r0 mov (sp)+,r5 rts pc _flush: mov r5,-(sp) mov sp,r5 jsr pc,fl mov (sp)+,r5 rts pc fl: mov _fout+4,r0 beq 1f sub $_fout+6,r0 mov r0,0f mov _fout,r0 bne 2f inc r0 2: sys 0; 9f .data 9: sys write; _fout+6; 0:.. .text 1: mov $_fout+6,_fout+4 mov $512.,_fout+2 cmp _fout,$2 bhi 1f mov $1,_fout+2 1: rts pc .bss _fout: .=.+518. mov r5,-(sp) mov sp,r5 mov _fout+4,r0 bne 1f jsr pc,fl mov _fout+4,r0 1: movb 4(r5),(r0)+ beq 1f inc _fout+4 dec _fout+2 bgt 1f jsr pc,fl 1: mov 4(r5),r0 mov (sp)+,r5 rts pc _flush: mov r5,-(sp) mov sp,r5 jsr pc,fl mov (sp)+,r5 rts pc fl: mov _fout+4,r0 beq 1f sub $_fout+6,r0 mov r0,0f mov _fout,r0 bne 2f inc r0 2: sys 0; 9f .data 9: sys write; _fout+6; 0:.. .text 1: mov $_fout+6,_fout+4 mov $512.,_fout+ int (*qscmp)(); int qses; qsort(a, n, es, fc) char *a; int n, es; int (*fc)(); { qscmp = fc; qses = es; qs1(a, a+n*es); } qs1(a, l) char *a, *l; { register char *i, *j, *es; char *lp, *hp; int n, c; es = qses; start: if((n=l-a) <= es) return; n = ((n/(2*es))*es) & 077777; hp = lp = a+n; i = a; j = l-es; for(;;) { if(i < lp) { if((c = (*qscmp)(i, lp)) == 0) { qsexc(i, lp =- es); continue; } if(c < 0) { i =+ es; continue; } } loop: if(j > hp) { if((c = (*qscmp)(hp, j)) == 0) { qsexc(hp =+ es, j); goto loop; } if(c > 0) { if(i == lp) { qstexc(i, hp =+ es, j); i = lp =+ es; goto loop; } qsexc(i, j); j =- es; i =+ es; continue; } j =- es; goto loop; } if(i == lp) { if(lp-a >= l-hp) { qs1(hp+es, l); l = lp; } else { qs1(a, lp); a = hp+es; } goto start; } qstexc(j, lp =- es, i); j = hp =- es; } } qsexc(i, j) char *i, *j; { register char *ri, *rj, c; int n; n = qses; ri = i; rj = j; do { c = *ri; *ri++ = *rj; *rj++ = c; } while(--n); } qstexc(i, j, k) char *i, *j, *k; { register char *ri, *rj, *rk; char c; int n; n = qses; ri = i; rj = j; rk = k; do { c = *ri; *ri++ = *rk; *rk++ = *rj; *rj++ = c; } while(--n); } = l-hp) { qs1(hp+es, l); l = lp; } else { qs1(a, lp); a = hp+es; } goto start; } qstexc(j, lp =- es, i); j = hp =- es; } } qsexc(i, j) char *i, *j; { register char *ri, *rj, c;/ C library -- read / nread = read(file, buffer, count); / / nread ==0 means eof; nread == -1 means error .globl _read, cerror _read: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 mov 6(r5),0f mov 8(r5),0f+2 sys 0; 9f bec 1f jmp cerror 1: mov (sp)+,r5 rts pc .data 9: sys read; 0:..; .. (--n); } = l-hp) { qs1(hp+es, l); l = lp; } else { qs1(a, lp); a = hp+es; } goto start; } qstexc(j, lp =- es, i); j = hp =- es; } } qsexc(i, j) char *i, *j; { register char *ri, *rj, c;/ C library -- reset, setexit / reset(x) / will generate a "return" from / the last call to / setexit() / by restoring sp, r5 / and doing a return. / The returned value is x; on the original / call the returned value is 0. / / useful for going back to the main loop / after a horrible error in a lowlevel / routine. .globl _setexit .globl _reset .globl csv, cret _setexit: mov r5,sr5 mov (sp),spc mov sp,ssp clr r0 rts pc _reset: jsr r5,csv mov 4(r5),r0 1: cmp (r5),sr5 beq 1f mov (r5),r5 bne 1b / panic -- r2-r4 lost mov ssp,sp mov sr5,r5 mov spc,(sp) rts pc 1: mov spc,2(r5) jmp cret .bss sr5: .=.+2 spc: .=.+2 ssp: .=.+2 oing a return. / The returned value is x; on the original / call the returned value is 0. / / useful for going back to the main loop / after a horrible error in a lowlevel / routine. .globl _setexit .globl _reset .globl csv, cret _setexit: mov r5,sr5 mov (sp),spc mov sp,ssp clr r0 rts pc _reset: jsr r5,csv mov 4(r5),r0 1: cmp (r5),sr5 beq 1f mov (r5),r5 bne 1b // C return sequence (obsolete) .globl retrn retrn: mov r5,sp mov (sp)+,r5 rts pc jmp cret .bss sr5: .=.+2 spc: .=.+2 ssp: .=.+2 oing a return. / The returned value is x; on the original / call the returned value is 0. / / useful for going back to the main loop / after a horrible error in a lowlevel / routine. .globl _setexit .globl _reset .globl csv, cret _setexit: mov r5,sr5 mov (sp),spc mov sp,ssp clr r0 rts pc _reset: jsr r5,csv mov 4(r5),r0 1: cmp (r5),sr5 beq 1f mov (r5),r5 bne 1b /rin() { double d; register n, c, f; d = 0.; f = 0; n = 0; loop: c = getchar(); if(c == '\0') exit(); if(c == '-') { f++; goto loop; } if(c == '.') { n++; goto loop; } if(c>='0' && c<='9') { if(n) n++; d = d*10.+c-'0'; goto loop; } if(f) d = -d; for(f=1; f 0 && **++argv == '-') switch(*++*argv) { case 'd': byday++; continue; case 'w': if (--argc>0) wtmp = *++argv; continue; case 'p': pflag++; continue; } pcount = argc; pptr = argv; if (fopen(wtmp, &fin) < 0) { printf("No %s\n", wtmp); exit(-1); } printf("Total user connect time in hours:\n"); for(;;) { ip = &ibuf; for (i=0; i<16; i++) { if ((c=getc(&fin)) < 0) goto brk; *ip++ = c; } if(ibuf.line[0]=='R' && ibuf.line[1]=='L') continue; fl = 0; for (i=0; i<8; i++) { if (i==0) ibuf.name[i] =& ~0200; c = ibuf.name[i]; if('0'<=c&&c<='9'||'a'<=c&&c<='z'||'A'<=c&&c<='Z') { if (fl) goto skip; continue; } if (c==' ' || c=='\0') { fl++; ibuf.name[i] = '\0'; } else goto skip; } loop(); skip: continue; } brk: ibuf.name[0] = '\0'; ibuf.line[0] = '!'; ibuf.line[1] = 'B'; time(&ibuf.time); loop(); print(); exit(0); } loop() { double ltod(); register i; register struct tbuf *tp; register struct ubuf *up; ibuf.time = ltod(&ibuf.time)/60.; if(ibuf.line[0] == 'O' && ibuf.line[1] == 'T') { dtime = ibuf.time; return; } if(ibuf.line[0] == 'N' && ibuf.line[1] == 'T') { if(dtime == 0.) return; for(tp = tbuf; tp < &tbuf[TSIZE]; tp++)  tp->ttime =+ ibuf.time-dtime; dtime = 0.; return; } if (lastime>ibuf.time || lastime+(1.5*day) midnight) { upall(1); print(); newday(); for (up=ubuf; up < &ubuf[USIZE]; up++) up->utime = 0.0; } if (ibuf.line[0] == '!' && ibuf.line[1] == 'B') { ibuf.name[0] = '\0'; upall(0); return; } if((i=tmap()) < 0) return; tp = &tbuf[i]; update(tp, 0); } print() { int i; float ttime, t; ttime = 0.0; for (i=0; i0.0) ttime =+ t; if (pflag && ubuf[i].utime > 0.0) { printf("\t%-8.8s%6.2f\n", ubuf[i].name, ubuf[i].utime/60.); } } if (ttime > 0.0) { pdate(); printf("\ttotal%9.2f\n", ttime/60.); } } upall(f) { register struct tbuf *tp; for (tp=tbuf; tp < &tbuf[TSIZE]; tp++) update(tp, f); } update(tp, f) struct tbuf *tp; { int i, j; struct ubuf *up; double t, t1; if (f) t = midnight; else t = ibuf.time; if (tp->userp) { t1 = t - tp->ttime; if (t1>0.0 && t1 < 1.5*day) tp->userp->utime =+ t1; } tp->ttime = t; if (f) return; if (ibuf.name[0]=='\0') { tp->userp = 0; return; } for (up=ubuf; up < &ubuf[USIZE]; up++) { if (up->name[0] == '\0') break; for (j=0; j<8 && up->name[j]==ibuf.name[j]; j++); if (j>=8) break; } for (j=0; j<8; j++) up->name[j] = ibuf.name[j]; tp->userp = up; } among(i) { register j, k; register char *p; if (pcount==0) return(1); for (j=0; j midnight) break; yrs++; tim =+ year; } days = (midnight-tim-720.)/day; montab[1] = 28; if(yrs%4 == 0) montab[1]++; for (mons=0; montab[mons]<=days; mons++) days =- montab[mons]; mons =% 12; printf("%s %2d", monasc[mons], days+1); } tmap() { register int i; struct{ char lobyte; char hibyte; }; for(i=0;i 1) acct(argv[1]); else acct(0); if (errno) { perror("accton"); exit(1); } exit(0); } =% 12; printf("%s %2d", monasc[mons], days+1); } tmap() { register int i; struct{ char lobyte; char hibyte; }; for(i=0;i= arbuf.date) #endif #ifndef LONG && stbuf.mdate[0] > arbuf.date[0] || (stbuf.mdate[0] == arbuf.date[0] && stbuf.mdate[1] >= arbuf.date[1])) #endif goto sk; f = creat(file, arbuf.mode & 07777); if(f < 0) { error("%s cannot create\n", file); goto sk; } mesg('x'); copyfil(af, f, IODD); close(f); continue; } sk: mesg('c'); copyfil(af, -1, IODD+SKIP); } } pcmd() { if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { if(FLGV) printf("\n\n%.14s:\n\n",file); copyfil(af, 1, IODD); continue;  } copyfil(af, -1, IODD+SKIP); } } mcmd() { register char *fro, *to; init(); if(getaf()) noar(); tf2nam = mktemp("/tmp/v2XXXXX"); close(creat(tf2nam, 0600)); tf2 = open(tf2nam, 2); if(tf2 < 0) { error("cannot create third temp\n"); done(); } while(!getdir()) { bamatch(); if(match()) { if(FLGN) { fro = trim(rename()); if(fro != file) for(file = to = arbuf.name; to < arbuf.name+14; *to++ = *fro ? *fro++ : '\0'); } mesg('m'); copyfil(af, tf2, IODD+OODD+HEAD); continue; } mesg('c'); copyfil(af, tf, IODD+OODD+HEAD); } install(); } tcmd() { if(getaf()) noar(); while(!getdir()) { if(namc == 0 || match()) { if(FLGV) longt(); printf("%s\n", trim(file)); } copyfil(af, -1, IODD+SKIP); } } init() { tfnam = mktemp("/tmp/vXXXXX"); close(creat(tfnam, 0600)); tf = open(tfnam, 2); if(tf < 0) { error("cannot create temp file\n"); done(); } buf[0] = NARMAG; write(tf, buf, 2); } getaf() { af = open(arnam, 0); if(af < 0)  return(1); buf[0] = 0; read(af, buf, 2); if(buf[0] != NARMAG) { error("%s not in archive format\n", arnam); done(); } return(0); } usage() { error("usage: ar [%s][%s] archive files ...\n", opt, man); done(); } noar() { error("%s does not exist\n", arnam); done(); } done() { if(tfnam) unlink(tfnam); if(tf1nam) unlink(tf1nam); if(tf2nam) unlink(tf2nam); exit(errcode); } notfound() { register i; for(i=0; i 0) write(af, buf, i); if(tf2nam) { seek(tf2, 0, 0); while((i = read(tf2, buf, 512)) > 0) write(af, buf, i); } if(tf1nam) { seek(tf1, 0, 0); while((i = read(tf1, buf, 512)) > 0) write(af, buf, i); } } /* * insert the file 'file' * into the temporary file */ movefil(f) { register char *cp; register i; cp = trim(file); for(i=0; i<14; i++) if(arbuf.name[i] = *cp) cp++; #ifdef LONG arbuf.size = itol(stbuf.siz0&0377, stbuf.siz1); arbuf.date = stbuf.mdate; #endif #ifndef LONG arbuf.size0 = stbuf.siz0&0377; arbuf.size1 = stbuf.siz1; arbuf.date[0] = stbuf.mdate[0]; arbuf.date[1] = stbuf.mdate[1]; #endif arbuf.uid = stbuf.usrid; arbuf.gid = stbuf.grpid; arbuf.mode = stbuf.flags; copyfil(f, tf, OODD+HEAD); close(f); } stats() { register f; f = open(file, 0); if(f < 0) return(f); if(fstat(f, &stbuf) < 0) { close(f); return(-1); } return(f); } /* * copy next file * size given in arbuf */ copyfil(fi, fo, flag) { register char *i, *o; if(flag & HEAD) write(fo, &arbuf, sizeof arbuf); #ifdef LONG while(arbuf.size > 0) { i = o = 512; if(arbuf.size < i) { i = o = arbuf.size; #endif #ifndef LONG while(arbuf.size0 >= 0 && arbuf.size1) { i = o = 512; if(arbuf.size0==0 && arbuf.size1 1) printf("%c - %s\n", c, file); } rename() { register char *p, *s; char name_buf[512]; printf("n - %s?",file); flush(); if(!read(0, p=s=name_buf, sizeof name_buf)) *s=0; while(*p) switch(*p++) { case '\n': *--p = 0; continue; case ':': case '*': case '[': case ']': case '(': case ')': case '=': case '?': case '<': case '>': case '"': error("illegal char '%c'\n", p[-1]); *s=0; } return(*s ? s : file); } trim(s) char *s; { register char *p1, *p2; for(p1 = s; *p1; p1++) ; while(p1 > s) { if(*--p1 != '/') break; *p1 = 0; } p2 = s; for(p1 = s; *p1; ) if(*p1++ == '/') p2 = p1; return(p2); } #define IFMT 060000 #define ISARG 01000 #define LARGE 010000 #define SUID 04000 #define SGID 02000 #define ROWN 0400 #define WOWN 0200 #define XOWN 0100 #define RGRP 040 #define WGRP 020 #define XGRP 010 #define ROTH 04 #define WOTH 02 #define XOTH 01 #define STXT 01000 longt() { register char *cp; register t; pmode(); printf("%3d/%1d", arbuf.uid&0377, arbuf.gid&0377); #ifdef LONG printf("%8s", locv(arbuf.size)); cp = ctime(&arbuf.date); #endif #ifndef LONG printf("%8s", locv(arbuf.size0,arbuf.size1)); cp = ctime(arbuf.date); #endif printf(" %-6.6s %-4.4s ", cp+4, cp+20); } int m1[] { 1, ROWN, 'r', '-' }; int m2[] { 1, WOWN, 'w', '-' }; int m3[] { 2, SUID, 's', XOWN, 'x', '-' }; int m4[] { 1, RGRP, 'r', '-' }; int m5[] { 1, WGRP, 'w', '-' }; int m6[] { 2, SGID, 's', XGRP, 'x', '-' }; int m7[] { 1, ROTH, 'r', '-' }; int m8[] { 1, WOTH, 'w', '-' }; int m9[] { 2, STXT, 't', XOTH, 'x', '-' }; int *m[] { m1, m2, m3, m4, m5, m6, m7, m8, m9}; pmode() { register int **mp; for (mp = &m[0]; mp < &m[9];) select(*mp++); } select(pairp) int *pairp; { register int n, *ap; ap = pairp; n = *ap++; while (--n>=0 && (arbuf.mode&*ap++)==0) ap++; putchar(*ap); } #ifndef LONG lsubi(lng,short) int *lng; { register int *l; l=lng; *l++ =- (l[1]>=0 && l[1] < short); *l =- short; } #endif error(fmt, arg1, arg2) { extern fout; if(FLGS == 0) { fout = 2; printf(fmt, arg1, arg2); fout = 1; } errcode++; } 3, m4, m5, m6, m7, m8, m9}; pmode() { register int **mp; for (mp = &m[0]; mp < &m[9];) select(*mp++); } select(pairp) int *pairp; { register int n, *ap; ap = pairp; n = *ap++; while (--n>=0 && (arbuf.mode&*ap++)==0) ap++; putchar(*ap); } #ifndef LONG lsubi(lng,short) int *lng; { register int *l; l=lng; *l++ =- (l[1]>=0 && l[1] < short); *l =- short; } #endif error(fmt, arg1, arg2) { extern fout; if(FLGS == 0) { char dayw[] { " S M Tu W Th F S" }; char *smon[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", }; char string[432]; main(argc, argv) char *argv[]; { register y, i, j; int m; if(argc < 2) { printf("usage: cal [month] year\n"); exit(); } if(argc == 2) goto lng; /* * print out just month */ m = number(argv[1]); if(m<1 || m>12) goto badarg; y = number(argv[2]); if(y<1 || y>9999) goto badarg; printf(" %s %l\n", smon[m-1], y); printf("%s\n", dayw); cal(m, y, string, 24); for(i=0; i<6*24; i=+24) pstr(string+i, 24); exit(); /* * print out complete year */ lng: y = number(argv[1]); if(y<1 || y>9999) goto badarg; printf("\n\n\n"); printf(" %l\n", y); printf("\n"); for(i=0; i<12; i=+3) { for(j=0; j<6*72; j++) string[j] = '\0'; printf(" %s", smon[i]); printf(" %s", smon[i+1]); printf(" %s\n", smon[i+2]); printf("%s %s %s\n", dayw, dayw, dayw); cal(i+1, y, string, 72); cal(i+2, y, string+23, 72); cal(i+3, y, string+46, 72); for(j=0; j<6*72; j=+72) pstr(string+j, 72); } printf("\n\n\n"); exit(); badarg: printf("Bad argument\n"); } number(str) char *str; { register n, c; register char *s; n = 0; s = str; while(c = *s++) { if(c<'0' || c>'9') return(0); n = n*10 + c-'0'; } return(n); } pstr(str, n) char *str; { register i; register char *s; s = str; i = n; while(i--) if(*s++ == '\0') s[-1] = ' '; i = n+1; while(i--) if(*--s != ' ') break; s[1] = '\0';  printf("%s\n", str); } char mon[] { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, }; cal(m, y, p, w) char *p; { register d, i; register char *s; s = p; d = jan1(y); mon[2] = 29; mon[9] = 30; switch((jan1(y+1)+7-d)%7) { /* * non-leap year */ case 1: mon[2] = 28; break; /* * 1752 */ default: mon[9] = 19; break; /* * leap year */ case 2: ; } for(i=1; i 9) *s = i/10+'0'; s++; *s++ = i%10+'0'; s++; if(++d == 7) { d = 0; s = p+w; p = s; } } } /* * return day of the week * of jan 1 of given year */ jan1(yr) { register y, d; /* * normal gregorian calendar * one extra day per four years */ y = yr; d = 4+y+(y+3)/4; /* * julian calendar * regular gregorian * less three days per 400 */ if(y > 1800) { d =- (y-1701)/100; d =+ (y-1601)/400; } /* * great calendar changeover instant */  if(y > 1752) d =+ 3; return(d%7); } = i/10+'0'; s++; *s++ = i%10+'0'; s++; if(++d == 7) { d = 0; s = p+w; p = s; } } } /* * return day of the week * of jan 1 of given year */ jan1(yr) { register y, d; /* * normal gregorian calendar * one extra day per four years */ y = yr; d = 4+y+(y+3)/4; /* * julian calendar * regular gregorian * less three days per 400 */ if(y > 1800) { d =- (y-1701)/100; d =+ (y-1601)/400; } /* * great calendar changeover instant */ # char *dargv[] { "/dev/rrf0", "/dev/rrp0", "/dev/rrp2", 0 }; #define NINODE 16*16 #define NI 20 #include "../head/ino.h" #include "../head/filsys.h" struct inode inode[NINODE]; struct filsys sblock; int sflg; int headpr; int ilist[NI] { -1}; int fi; char *ecount; char *lasts; int ino; int nerror; int nfiles; struct dir { int ino; char name[14]; }; main(argc, argv) char **argv; { register char **p; register int n, *lp; ecount = sbrk(0); if (argc == 1) { for (p = dargv; *p;) check(*p++); return(nerror); } while (--argc) { argv++; if (**argv=='-') switch ((*argv)[1]) { case 's': sflg++; continue; case 'i': lp = ilist; while (lp < &ilist[NI-1] && (n = atoi(argv[1]))) { *lp++ = n; argv++; argc--; } *lp++ = -1; continue; default: printf("Bad flag %c\n", (*argv)[1]); nerror++; } check(*argv); } return(nerror); } check(file) char *file; { register i, j; fi = open(file, 0); if(fi < 0) { printf("cannot open %s\n", file); nerror++; return; } headpr = 0; printf("%s:\n", file); sync(); bread(1, &sblock, 512); nfiles = sblock.s_isize*16; if (lasts <= nfiles) { if ((sbrk(nfiles - lasts + 1)) == -1) { printf("Not enough core\n"); exit(04); } lasts = nfiles+1; } for (i=0; i<=nfiles; i++) ecount[i] = 0; ino = 0; for(i=0; inoi_mode&IALLOC) == 0) return; if((ip->i_mode&IFMT) != IFDIR) return; doff = 0; while (doffi_size1 && (dp = dread(ip, doff))) { doff =+ 16; if (dp->ino==0) continue; if (dp->ino > nfiles || dp->ino < 1) { printf("%5u bad; %u/%.14s\n", dp->ino, ino, dp->name); nerror++; continue; } for (i=0; ilist[i] != -1; i++) if (ilist[i]==dp->ino) { printf("%5l arg; %u/%.14s\n", dp->ino, ino, dp->name); nerror++; } ecount[dp->ino]++; } } pass2(aip) { register struct inode *ip; register i; ip = aip; i = ino; if ((ip->i_mode&IALLOC)==0 && ecount[i]==0) return; if (ip->i_nlink==ecount[i] && ip->i_nlink!=0) return; if (headpr==0) { printf(" entries link cnt\n"); headpr++; } printf("%u %d %d\n", ino,  ecount[i]&0377, ip->i_nlink&0377); } dread(aip, aoff) { register b, off; register struct inode *ip; static ibuf[256]; static char buf[512]; off = aoff; ip = aip; if ((off&0777)==0) { if (off==0177000) { printf("Monstrous directory %u\n", ino); return(0); } if ((ip->i_mode&ILARG)==0) { if (off>=010000 || (b = ip->i_addr[off>>9])==0) return(0); bread(b, buf, 512); } else { if (off==0) { if (ip->i_addr[0]==0) return(0); bread(ip->i_addr[0], ibuf, 512); }  if ((b = ibuf[(off>>9)&0177])==0) return(0); bread(b, buf, 512); } } return(&buf[off&0777]); } bread(bno, buf, cnt) { seek(fi, bno, 3); if(read(fi, buf, cnt) != cnt) { printf("read error %d\n", bno); exit(++nerror); } } putchar(c) char c; { write(2, &c, 1); } ((ip->i_mode&ILARG)==0) { if (off>=010000 || (b = ip->i_addr[off>>9])==0) return(0); bread(b, buf, 512); } else { if (off==0) { if (ip->i_addr[0]==0) return(0); bread(ip->i_addr[0], ibuf, 512); } # /* C command */ # define SYMSIZ 400 # define SBSIZE 10000 # define MAXINC 10 # define CHSPACE 1000 # define EXPSIZE 500 # define LINELEN 500 # define NPREDEF 10 char sbf[SBSIZE]; char *tmp0; char *tmp1; char *tmp2; char *tmp3; char *tmp4; char *tmp5; char *outfile; char ts[CHSPACE+50]; char *tsa ts; char *tsp ts; char *av[50]; char *clist[50]; char *llist[50]; int instring; int pflag; int sflag; int cflag; int eflag; int exflag; int oflag; int proflag; int hflag; int depth; int *ibuf; int *ibufs[MAXINC]; int ifno; int *obuf; extern int fout; char *lp; char *line; char *predef[NPREDEF+1]; char **pdp &predef[0]; char *sprefix "/usr/include"; char *compool "/compool/"; char *homedir; /* home directory for include statements */ int lineno[MAXINC]; int exfail; struct symtab { char name[8]; char *value; } *symtab; struct symtab *defloc; struct symtab *incloc; struct symtab *eifloc; struct symtab *ifdloc; struct symtab *ifnloc; struct symtab *unxloc; struct symtab *lneloc; struct symtab *prdloc; int trulvl; int flslvl; char *stringbuf; char *pass0 "/lib/c0"; char *pass1 "/lib/c1"; char *pass2 "/lib/c2"; char *pref "/lib/crt0.o"; int multflg; char multm[] "Warning - \"%.8s\" multiply defined"; main(argc, argv) char *argv[]; { char *t; char *savetsp; char *assource; int nc, nl, i, j, c, f20, nxo; int dexit(); i = nc = nl = f20 = nxo = 0; while(++i < argc) { if(*argv[i] == '-') switch (argv[i][1]) { default: goto passa; case 'S': sflag++; cflag++; break; case 'o': if (++i < argc) { outfile = argv[i]; if ((t=getsuf(outfile))=='c'||t=='o') { error("Would overwrite %s", outfile); exit(8); } } break; case 'O': oflag++; break; case 'p': proflag++; pref = "/lib/mcrt0.o"; break; case 'E': exflag++; case 'P': pflag++; case 'c': cflag++; break; case 'C': compool = argv[i] + 2; break; case 'f': pref = "/lib/fcrt0.o"; pass0 = "/lib/fc0"; pass1 = "/lib/fc1"; break; case '2': if(argv[i][2] == '\0') pref = "/lib/crt2.o"; else { pref = "/lib/crt20.o"; f20 = 1; } break; case 'D': if (pdp >= &predef[NPREDEF]) { printf("Too many predefines\n"); exit(1); } *pdp++ = argv[i] + 2; break; case 'I': sprefix=argv[i]+2; break; case 't': if (argv[i][2]=='0') pass0 = "/usr/c/c0"; if (argv[i][2]=='1') pass1 = "/usr/c/c1"; if (argv[i][2]=='2') pass2 = "/usr/c/c2"; break; case 'B': pass0 = "/usr/c/oc0"; pass1 = "/usr/c/oc1"; break; case 'h': hflag++; homedir = ""; break; } else { passa: t = argv[i]; if((c=getsuf(t))=='c' || c=='s'|| exflag) { clist[nc++] = t; t = setsuf(t, 'o'); } if (nodup(llist, t)) { llist[nl++] = t; if (getsuf(t)=='o') nxo++; } } } if(nc==0) goto nocom; if (pflag==0) { tmp0 = mktemp(copy("/tmp/ctm0XXXXX")); if (tmp0[1] == '\0' || close(creat(tmp0, 0400)) == -1) { printf("Can't create temp file\n"); exit(1); } } if ((signal(2, 1) & 01) == 0) /* interrupt */ signal(2, dexit); if ((signal(1, 1) & 01) == 0) /* hangup */ signal(1, dexit); if ((signal(15, 1) & 01) == 0) /* terminate */ signal(15, dexit); (tmp1 = copy(tmp0))[8] = '1'; (tmp2 = copy(tmp0))[8] = '2'; (tmp3 = copy(tmp0))[8] = '3'; if (oflag) (tmp5 = copy(tmp0))[8] = '5'; if (pflag==0) (tmp4 = copy(tmp0))[8] = '4'; for (i=0; i1) printf("%s:\n", clist[i]); if (getsuf(clist[i])=='s') { assource = clist[i]; goto assemble; } else assource = tmp3; av[0] = "c0"; if (pflag) tmp4 = setsuf(clist[i], 'i'); savetsp = tsp; av[1] = expand(clist[i]); tsp = savetsp; if (pflag || exfail) continue; if (av[1] == 0) { cflag++; eflag++; continue; } av[2] = tmp1; av[3] = tmp2; if (proflag) { av[4] = "-P"; av[5] = 0; } else av[4] = 0; if (callsys(pass0, av)) { cflag++; eflag++; continue; } av[0] = "c1"; av[1] = tmp1; av[2] = tmp2; if (sflag) assource = tmp3 = setsuf(clist[i], 's'); av[3] = tmp3; if (oflag) av[3] = tmp5; av[4] = 0; if(callsys(pass1, av)) { cflag++; eflag++; continue; } if (oflag) { av[0] = "c2"; av[1] = tmp5; av[2] = tmp3; av[3] = 0; if (callsys(pass2, av)) { cflag++; eflag++; continue; } unlink(tmp5); } if (sflag) continue; assemble: av[0] = "as"; av[1] = "-u"; av[2] = "-o"; av[3] = setsuf(clist[i], 'o'); av[4] = assource; av[5] = 0; cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); if (callsys("/bin/as", av) > 1) { cflag++; eflag++; continue; } } nocom: if (cflag==0 && nl!=0) { i = 0; av[0] = "ld"; av[1] = "-X"; av[2] = pref; j = 3; if (outfile) { av[j++] = "-o"; av[j++] = outfile; } while(i3) { if (flslvl==0 &&(state+!lookup(namep,-1)->name[0])==5) trulvl++; else flslvl++; out: while (c!='\n' && c!= '\0') c = getch(); return(c); } if (state==3) /* include */ if (*namep != '"' && *namep != '<') { error("Bad include syntax", 0); state=1; } if (state!=2 || flslvl==0) { ungetc(c); np = lookup(namep, state); c = getch(); } if (state==1) { if (np==defloc) state = 2; else if (np==incloc) state = 3; else if (np==ifnloc) state = 4; else if (np==ifdloc) state = 5; else if (np==eifloc) { if (flslvl) --flslvl; else if (trulvl) --trulvl; else errback("If-less endif"); goto out; } else if (np==lneloc) { puts("# "); lp=line; for(; c !='\n' && c != '\0'; c=getch()) if (!pflag || exflag) sch(c); sch('\0'); return(c); } else { errback("Undefined control"); while (c!='\n' && c!='\0') c = getch(); return(c); } } else if (state==2) { if (flslvl) goto out; valuep = stringbuf; if (c != '\n' && c != 0) { savch(c); while ((c=getch())!='\n' && c!='\0') savch(c); } savch('\0'); if (multflg) if (!streq(np->value, valuep)) { lineno[ifno]--; warn(multm,np->name); lineno[ifno]++; } np->value = valuep; return(1); } continue; } else if ((sc=c) == '\'' || sc== '"' || (state==3 && sc== '<')) { sch(sc); filname = lp; if (sc== '<') { sc= '>'; for(cp=sprefix; *cp; cp++) *lp++ = *cp; *lp++= '/'; homedir = ""; } instring++; while ((c=getch())!=sc && c!='\n' && c!='\0') { sch(c); if (c=='\\') sch(getch()); } instring = 0; if (flslvl) goto out; if (state==3) { if (flslvl) goto out; *lp = '\0'; while ((c=getch())!='\n' && c!='\0'); if (ifno+1 >=MAXINC) error("Unreasonable include nesting",0); if(ibufs[++ifno]==0)  ibufs[ifno]=sbrk(518); if (fopen(cat(homedir,filname),ibufs[ifno])<0 && fopen(cat(compool,filname),ibufs[ifno])<0) { ifno--; errback("Missing file %s", filname); dexit(1); } else ibuf = ibufs[ifno]; puts("\n# 1 \""); puts(filname); puts("\""); lineno[ifno]=1; fnames[ifno] = copy(filname); return(c); } } sch(c); c = getch(); } sch('\0'); if (state>1) errback("Control syntax"); return(c); } insym(sp, namep) struct symtab **sp; char *namep; { register struct symtab *np; *sp = np = lookup(namep, 1); np->value = np->name; } warn(s, x) { int olfout; olfout = fout; flush(); if (exflag) fout=2; if (fnames[ifno]) printf("%s: %d: ", fnames[ifno], lineno[ifno]); printf(s, x); putchar('\n'); flush(); fout=olfout; } error(s, x) { warn(s, x); exfail++; cflag++; eflag++; } errback(s,x) { lineno[ifno]--; error(s,x); lineno[ifno]++; } sch(c) { register char *rlp; rlp = lp; if (rlp==line+LINELEN-2) error("Line overflow"); *rlp++ = c; if (rlp>line+LINELEN-1) rlp = line+LINELEN-1; lp = rlp; } savch(c) { *stringbuf++ = c; if (stringbuf-sbf < SBSIZE) return; error("Too much defining"); dexit(1); } getch() { register int c; loop: if ((c=getc1())=='/' && !instring) { if ((c=getc1())!='*') { ungetc(c); return('/'); } for(;;) { c = getc1(); cloop: switch (c) { case '\0': return('\0'); case '*': if ((c=getc1())=='/') goto loop; goto cloop; case '\n': putc('\n', obuf); continue; } } } return(c); } char pushbuff[EXPSIZE]; char *pushp pushbuff; ungetc(c) { *++pushp = c; if (pushp>pushbuff+EXPSIZE) { error("Too much backup"); dexit(8); } } getc1() { register c; if (*pushp !=0) return(*pushp--); depth=0; if ((c = getc(ibuf)) < 0 && ifno>0) { close(ibuf[0]); ibuf = ibufs[--ifno]; puts("\n# "); puts(itoa(lineno[ifno])); puts(" \""); puts(fnames[ifno]); puts("\"\n"); c = getc1(); if (c=='\n') lineno[ifno]--; } if (c<0) return(0); if (c=='\n' ) lineno[ifno]++; return(c); } lookup(namep, enterf) char *namep; { register char *np, *snp; register struct symtab *sp; int i, c, around; multflg = 0; np = namep; snp = &np[8]; around = i = 0; while (c = *np++ && np < snp) i =+ c; i =% SYMSIZ; sp = &symtab[i]; while (sp->name[0]) { snp = sp; np = namep; while (*snp++ == *np) if (*np++ == '\0' || np==namep+8) { if (!enterf) subst(namep, sp); else multflg++; return(sp); } if (++sp >= &symtab[SYMSIZ]) if (around++) { error("Too many defines"); dexit(1); } else sp = symtab; } if (enterf>0) { snp = namep; for (np = &sp->name[0]; np < &sp->name[8];) if (*np++ = *snp) snp++; } return(sp); } char revbuff[200], *bp; backsch(c) { if (bp-revbuff > 200) error("Excessive define looping", bp--); *bp++ = c; } subst(np, sp) char *np; struct symtab *sp; { register char *vp; int macflg; lp = np; bp = revbuff; if (depth++>100) { error("Define recursion loop\n"); return; } if ((vp = sp->value) == 0) return; macflg= (*vp == '('); /* arrange that define unix unix still has no effect, avoiding rescanning */ while (blank(*vp)) vp++; if (streq(sp->name,vp)) { while (*vp) sch(*vp++); return; } if (macflg) expdef(vp); else while (*vp) backsch(*vp++); while (bp>revbuff) ungetc(*--bp); } getsuf(as) char as[]; { register int c; register char *s; register int t; s = as; c = 0; while(t = *s++) if (t=='/') c = 0; else c++; s =- 3; if (c<=14 && c>2 && *s++=='.') return(*s); return(0); } setsuf(as, ch) char as[]; { register char *s, *s1; s = s1 = copy(as); while(*s) if (*s++ == '/') s1 = s; s[-1] = ch; return(s1); } callsys(f, v) char f[], *v[]; { int t, status; if ((t=fork())==0) { execv(f, v); printf("Can't find %s\n", f); exit(100); } else if (t == -1) { printf("Try again\n"); return(100); } while(t!=wait(&status)); if ((t=(status&0377)) != 0 && t!=14) { if (t!=2) /* interrupt */ { printf("Fatal error in %s\n", f); eflag = 8; } dexit(1); } return((status>>8) & 0377); } copy(as) char as[]; { register char *otsp, *s; otsp = tsp; s = as; while(*tsp++ = *s++); if (tsp >tsa+CHSPACE) tsp = tsa = expandch(); return(otsp); } expandch() { int i; i = alloc(CHSPACE+50); if (i == -1){ error("No space for file names"); dexit(8); } return(i); } cat(str1, str2) char *str1, *str2; { register char *otsp, *s; if (*str1 == '\0') return (str2); if (*str2 == '\0') return (str1); otsp = tsp; s = str1; while(*s) *tsp++ = *s++; s = str2; while(*tsp++ = *s++); if (tsp > tsa+CHSPACE) tsp = tsa = expandch(); return(otsp); } nodup(l, os) char **l, *os; { register char *t, *s; register int c; s = os; if (getsuf(s) != 'o') return(1); while(t = *l++) { while(c = *s++) if (c != *t++) break; if (*t=='\0' && c=='\0') return(0); s = os; } return(1); } cunlink(f) char *f; { if (f==0) return(0); return(unlink(f)); } expdef(proto) char *proto; { char buffer[EXPSIZE], *parg[20], *pval[20], name[20], *cspace, *wp; char protcop[EXPSIZE], *pr; int narg, k, c; pr = protcop; while (*pr++ = *proto++); if (pr>protcop+EXPSIZE){ error("Define prototype too big"); dexit(8); } proto= protcop; for (narg=0; (parg[narg] = token(&proto)) != 0; narg++) ; /* now scan input */ cspace = buffer; while ((c=getch()) == ' '); if (c != '(') { error("Defined function requires arguments"); return; } ungetc(c); for(k=0; pval[k] = coptok(&cspace, buffer+EXPSIZE); k++); if (k!=narg) { error("Define argument mismatch"); return; } while (c= *proto++) { if (!letter(c)) backsch(c); else { wp = name; *wp++ = c; while (letnum(*proto)) *wp++ = *proto++; *wp = 0; for (k=0; k 0 || stop >0) { if (stc == '\0') { error("Non terminated macro call"); val = 0; break; } if (stop == 0 && (stc == '"' || stc == '\'')) stop = stc; else if (stc==stop) stop=0; if ( stc == '\\') { stc = getch(); if (stop>0 || (stc != ',' && stc != '\\')) *(*cpp)++ = '\\'; *(*cpp)++ = stc; } else { *(*cpp)++ = stc; if (stop==0) { if (stc == '(') paren++; if (stc == ')') paren--; } } if (*cpp >= clim) { error("Define argument too long",0); dexit(8); } } *(*cpp)++ = 0; ungetc(stc); return(val); } letter(c) { if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c == '_')) return (1); else return(0); } letnum(c) { if (letter(c) || (c >= '0' && c <= '9')) return(1); else return(0); } streq(s,t) char *s, *t; { int c; while ( (c= *s++) == *t++) if (c==0) return(1); return(0); } puts(s) char *s; { int c; if (pflag && !exflag) return; while (c= *s++) putc(c, obuf); } itoa(n) { static char sb[20]; char *sp; sp = sb+19; *sp=0; if (n<=0) *--sp = '0'; else while (n) { *--sp = '0'+ n%10; n=n/10; } return(sp); } blank(c) { return(c==' ' || c== '\t'); } (c == '_')) return (1); else return(0); } letnum(c) { if (letter(c) || (c >= '0' && c <= '9')) return(1); else return(0); } streq(s,t) char *s, *t; { int c; while ( (c= *s++) == *t++) if (c==0) return(1); return(0); } puts(s) char *s; { int c; if (pflag && !exflag) return; while (c= *s++) putc(c, obuf); } itoa(n) { static char sb[20]; char *sp; sp = sb+19; *sp=0; if (n<=0) *--sp = '0'; else while (n) { *--/* diff - differential file comparison * * Uses an algorithm due to Harold Stone, which finds * a pair of longest identical subsequences in the two * files. * * The major goal is to generate the match vector J. * J[i] is the index of the line in file1 corresponding * to line i file0. J[i] = 0 if there is no * such line in file1. * * Lines are hashed so as to work in core. All potential * matches are located by sorting the lines of each file * on the hash (called value_____). In particular, this * collects the equivalence classes in file1 together. * Subroutine equiv____ replaces the value of each line in * file0 by the index of the first element of its * matching equivalence in (the reordered) file1. * To save space equiv_____ squeezes file1 into a single * array member______ in which the equivalence classes * are simply concatenated, except that their first * members are flagged by changing sign. * * Next the indices that point into member______ are unsorted_______ into * array class_____ according to the original order of file0. * * The cleverness lies in routine stone______. This marches * through the lines of file0, developing a vector klist_____ * of "k-candidates". At step i a k-candidate is a matched * pair of lines x,y (x in file0 y in file1) such that * there is a common subsequence of lenght k * between the first i lines of file0 and the first y * lines of file1, but there is no such subsequence for * any smaller y. x is the earliest possible mate to y * that occurs in such a subsequence. * * Whenever any of the members of the equivalence class of * lines in file1 matable to a line in file0 has serial number * less than the y of some k-candidate, that k-candidate * with the smallest such y is replaced. The new * k-candidate is chained (via pred____) to the current * k-1 candidate so that the actual subsequence can * be recovered. When a member has serial number greater * that the y of all k-candidates, the klist is extended. * At the end, the longest subsequence is pulled out * and placed in the array J by unravel_______. * * With J in hand, the matches there recorded are * check_____ed against reality to assure that no spurious * matches have crept in due to hashing. If they have, * they are broken, and "jackpot " is recorded--a harmless * matter except that a true match for a spuriously * mated line may now be unnecessarily reported as a change. * * Much of the complexity of the program comes simply * from trying to minimize core utilization and * maximize the range of doable problems by dynamically * allocating what is needed and reusing what is not. * The core requirements for problems larger than somewhat * are (in words) 2*length(file0) + length(file1) + * 3*(number of k-candidates installed), typically about * 6n words for files of length n. There is also space for buf1 * used which could, by moving data underfoot and reallocating * buf1 together with buf2, be completely overlaid. */ struct buf { int fdes; char data[516]; } *buf1, *buf2; struct cand { int x; int y; struct cand *pred; } cand; struct cand *newcand(); struct line { int serial; int value; } *file[2], line; int len[2]; int *class; /*will be overlaid on file[0]*/ int *member; /*will be overlaid on file[1]*/ struct cand **klist; /*will be overlaid on file[0] after class*/ int *J; /*will be overlaid on class*/ int *ixold; /*will be overlaid on klist*/ int *ixnew; /*will be overlaid on file[1]*/ int opt; /* -1,0,1 = -e,normal,-f */ int bflag; char *tempfile; /*used when comparing against std input*/ done() { unlink(tempfile); exit(0); } char *area; char *top; alloc(n) { register char *p; p = area; n = (n+1) & ~1; area =+ n; while(area > top) { if(sbrk(1024) == -1) { mesg("Out of space\n"); done(); } top =+ 1024; } return(p); } mesg(s) char *s; { while(*s) write(2,s++,1); } sort(a,n) /*shellsort CACM #201*/ struct line *a; { struct line w; register int j,m; struct line *ai; register struct line *aim; int k; for(j=1;j<=n;j=* 2) m = 2*j - 1; for(m=/2;m!=0;m=/2) { k = n-m; for(j=1;j<=k;j++) { for(ai = &a[j]; ai > a; ai =- m) { aim = &ai[m]; if(aim < ai) break; /*wraparound*/ if(aim->value > ai[0].value || aim->value == ai[0].value && aim->serial > ai[0].serial) break; w.value = ai[0].value; ai[0].value = aim->value; aim->value = w.value; w.serial = ai[0].serial; ai[0].serial = aim->serial; aim->serial = w.serial; } } } } unsort(f, l, b) struct line *f; int *b; { register int *a; register int i; a = alloc((l+1)*sizeof(a[0])); for(i=1;i<=l;i++) a[f[i].serial] = f[i].value; for(i=1;i<=l;i++) b[i] = a[i]; area = a; } filename(pa1, pa2) char **pa1, **pa2; { register char *a1, *b1, *a2; int buf[256]; int i, f; a1 = *pa1; a2 = *pa2; if(stat(a1,buf)!=-1&&(buf[2]&040000)!=0) { b1 = *pa1 = alloc(100); while(*b1++ = *a1++) ; b1[-1] = '/'; a1 = b1; while(*a1++ = *a2++) if(*a2 && *a2!='/' && a2[-1]=='/') a1 = b1; } else if(a1[0]=='-'&&a1[1]==0&&tempfile==0) { signal(2,done); *pa1 = tempfile = mktemp("/tmp/dXXXXX"); if((f=creat(tempfile,0600)) < 0) { mesg("Cannot creat"); mesg(tempfile); mesg("\n"); done(); } while((i=read(0,buf,512))>0) write(f,buf,i); close(f); } } prepare(i, arg) char *arg; { register char *temp; temp = file[i] = area; alloc(sizeof(line)); input(arg); len[i] = (area - temp)/sizeof(line) - 1; alloc(sizeof(line)); sort(file[i], len[i]); } input(arg) { register int h, i; register struct line *p; if(fopen(arg,buf1) == -1) { mesg("Cannot open "); mesg(arg); mesg("\n"); done(); } for(i=0; h=readhash(buf1);) { p = alloc(sizeof(line)); p->serial = ++i; p->value = h; } close(buf1->fdes); } equiv(a,n,b,m,c) struct line *a, *b; int *c; { register int i, j; i = j = 1; while(i<=n && j<=m) { if(a[i].value 3 && *argv[1]=='-') { argc--; argv++; while(*++*argv) { switch(**argv) { case 'e': opt = -1; break; case 'f': opt = 1; break; case 'b': bflag = 1; break; } } } if(argc!=3) { mesg("Arg count\n"); done(); } area = top = sbrk(0); filename(&argv[1], &argv[2]); filename(&argv[2], &argv[1]); buf1 = alloc(sizeof(*buf1)); if(argv[0][0]=='-' & argv[0][1]=='1') { k = argv[1]; argv[1] = argv[2]; argv[2] = k; } prepare(0, argv[1]); prepare(1, argv[2]); member = file[1]; equiv(file[0], len[0], file[1], len[1], member); class = file[0]; unsort(file[0], len[0], class); klist = &class[len[0]+2]; area = &member[len[1]+2]; k = stone(class, len[0], member, klist); J = class; unravel(klist[k]); ixold = klist; ixnew = file[1]; area = &ixnew[len[1]+2]; buf2 = alloc(sizeof(*buf2)); if(check(argv)) mesg("Jackpot\n"); output(argv); done(); } stone(a,n,b,c) int *a; int *b; struct cand **c; { register int i, k,y; int j, l; struct cand *oldc, *tc; int oldl; k = 0; c[0] = newcand(0,0,0); for(i=1; i<=n; i++) { j = a[i]; if(j==0) continue; y = -b[j]; oldl = 0; oldc = c[0]; do { if(y <= oldc->y) continue; l = search(c, k, y); if(l!=oldl+1) oldc = c[l-1]; if(l<=k) { if(c[l]->y <= y) continue; tc = c[l]; c[l] = newcand(i,y,oldc); oldc = tc; oldl = l; } else { c[l] = newcand(i,y,oldc); k++; break; } } while((y=b[++j]) > 0); } return(k); } struct cand * newcand(x,y,pred) struct cand *pred; { register struct cand *p; p = alloc(sizeof(cand)); p->x = x; p->y = y; p->pred = pred; return(p); } search(c, k, y) struct cand **c; { register int i, j, l; int t; i = 0; j = k+1; while((l=(i+j)/2) > i) { t = c[l]->y; if(t > y) j = l; else if(t < y) i = l; else return(l); } return(l+1); } unravel(p) struct cand *p; { register int i; for(i=0; i<=len[0]; i++) J[i] = 0; while(J[p->x] = p->y) p = p->pred; } /* check does double duty: 1. ferret out any fortuitous correspondences due to counfounding by hashing (which result in "jackpot") 2. collect random access indexes to the two files */ check(argv) char **argv; { register int i, j; int ctold, ctnew; int jackpot; char c,d; fopen(argv[1],buf1); fopen(argv[2],buf2); j = 1; ctold = ctnew = 0; ixold[0] = ixnew[0] = 0; jackpot = 0; for(i=1;i<=len[0];i++) { if(J[i]==0) { while(getc(buf1)!='\n') ctold++; ixold[i] = ++ctold; continue; } while(jfdes); close(buf2->fdes); return(jackpot); } blank(c) char c; { switch(c) { case '\t': case ' ': case '\n': return(1); } return(0); } output(argv) char **argv; { int m; register int i0, i1, j1; int j0; extern fout; fout = dup(1); buf1->fdes = open(argv[1],0); buf2->fdes = open(argv[2],0); m = len[0]; J[0] = 0; J[m+1] = len[1]+1; if(opt!=-1) for(i0=1;i0<=m;i0=i1+1) { while(i0<=m&&J[i0]==J[i0-1]+1) i0++; j0 = J[i0-1]+1; i1 = i0-1; while(i1=1;i0=i1-1) { while(i0>=1&&J[i0]==J[i0+1]-1&&J[i0]!=0) i0--; j0 = J[i0+1]-1; i1 = i0+1; while(i1>1&&J[i1-1]==0) i1--; j1 = J[i1-1]+1; J[i1] = j1; change(i1,i0,j1,j0); } if(m==0) change(1,0,1,len[1]); flush(); } change(a,b,c,d) { if(a>b&&c>d) return; if(opt!=1) { range(a,b,",%d"); putchar(a>b?'a':c>d?'d':'c'); if(opt!=-1) range(c,d,",%d"); } else { putchar(a>b?'a':c>d?'d':'c'); range(a,b," %d"); } putchar('\n'); if(opt==0) { fetch(ixold,a,b,buf1,"< "); if(a<=b&&c<=d) printf("---\n"); } fetch(ixnew,c,d,buf2,opt==0?"> ":""); if(opt!=0&&c<=d) printf(".\n"); } range(a,b,format) { if(a>b) printf("%d",b); if(a<=b) printf("%d",a); if(afdes,f[i-1],0); nc = read(lb->fdes,lb->data,f[i]-f[i-1]); printf(pref); for(j=0;jdata[j]); } } /* hashing has the effect of * arranging line in 7-bit bytes and then * summing 1-s complement in 16-bit hunks */ readhash(buf) { long sum, addend; register shift; register space; register t; struct { int hi, lo; }; sum = 1; space = 0; for(shift=0;;) { switch(t=getc(buf)) { case -1: return(0); case '\n': addend.hi = 0; addend.lo = sum.lo; addend =+ sum.hi; return(addend.lo+addend.hi); case '\t': case ' ': if(bflag) { space = 1; break; } default: if(space) { sum =+ 040L<1 && *argv[1] == '-') { argc--; argv++; arg = *argv; while(*arg) switch(*arg++) { case 'l': lflg++; continue; case 's': sflg++; continue; case 'i': dlist[ndlist++] = number(argv[1]); argc--; argv++; continue; case 'b': blist[nblist++] = number(argv[1]); argc--; argv++; continue; case 'g': great = number(argv[1]); argc--; argv++; continue; } } if (lflg) sflg = 0; fout = dup(1); argc--; argv++; fprintf("%s:\n", argv[0]); check(argv[0]); flush(); close(fout); fout = 1; if(argc > 1) execv("/bin/check", argv); } check(file) char *file; { struct inode buf[16]; int i, j; int compar(), cintr(); struct fname *dnp; fi = open(file, 0); if(fi < 0) { fprintf("cannot open %s\n", file); return; } sync(); bread(1, &sblock); if (lflg) { lfdes = creat(lfile, 0666); signal(2, cintr); dn = edn = sbrk(100*6); } else { bmap = sbrk(8192); icnt = sbrk(sblock.s_isize*16); } for(i=0; ipnum == 0) { if(dnp->inum != 1) j = 1; continue; } if (dnp->inum != i) { i = dnp->inum; printf("%d", i); } putchar('\t'); pfilename(dnp, 0); if(j) { j = 0; printf("/."); } putchar('\n'); } close(lfdes); unlink(lfile); return; } sync(); bread(1, &sblock); if(sflg) { close(fi); fi = open(file, 1); if(fi < 0) { fprintf("cannot write %s\n", file); return; } sblock.s_nfree = 0; sblock.s_ninode = 0; sblock.s_flock = 0; sblock.s_ilock = 0; sblock.s_fmod = 0; free(0); for(i=sblock.s_fsize-1; i>=sblock.s_isize+2; i--) { ndup = 0; chk(i, "URK", 0); if(ndup == 0) free(i); } bwrite(1, &sblock); close(fi); sync(); return; } while(i = alloc()) { if(chk(i, "free", 0)) break; nfree++; } if(ndup) printf("%l dups in free\n", ndup); ndup = 0; for(i=sblock.s_isize+2; iicnt[i] & 0377; if(j!=0 && j!=0200) printf("%6l %3o\n", i+1, j); } printf("spcl %6l\n", nspcl); printf("files %6l\n", nfile); printf("large %6l\n", nlarg); printf("direc %6l\n", ndir); printf("indir %6l\n", nindir); printf("used %6l\n", nused); printf("last %6l\n", hiwat); printf("free %6l\n", nfree); close(fi); } cintr() { unlink(lfile); exit(); } compar(p1, p2) struct fname *p1, *p2; { int i; i = p1->inum - p2->inum; if(i) return(i); return(p1->pnum - p2->pnum); } pass1(ip) struct inode *ip; { int buf[256]; int i, j, df; if((ip->i_mode&IALLOC) == 0) return; if (!lflg) { icnt->icnt[ino-1] =+ 0100; if(ip->i_nlink) icnt->icnt[ino-1] =+ 0100 + ip->i_nlink; }  if((ip->i_mode&IFCHR&IFBLK) != 0) { nspcl++; return; } df = 0; if((ip->i_mode&IFMT) == IFDIR) { df = ldiv(ip->i_size0, ip->i_size1, 16); if(lflg) { if(--nnf<0) { nnf = 100; edn = sbrk(6*101); } edn->pnum = 0; edn->inum = ino; edn++; } ndir++; } else if (lflg) return; nfile++; if((ip->i_mode&ILARG) != 0) { nlarg++; for(i=0; i<8; i++) if(ip->i_addr[i] != 0) { nindir++; if(chk(ip->i_addr[i], "idir", 0)) continue; bread(ip->i_addr[i], buf); for(j=0; j<256; j++) if(buf[j] != 0) chk(buf[j], "ldir", df); df =- 32; } return; } for(i=0; i<8; i++) { if(ip->i_addr[i] != 0) chk(ip->i_addr[i], "sdir", df); df =- 32; } } chk(i, s, df) char *i; { int n, b, j, buf[256]; struct { int ino; char name[14]; }; for(j=0; j= great && i) fprintf("%l geq; i=%l(%s)\n", i, ino, s); if(ino) { nused++; if(i > hiwat) hiwat = i; } if(i=sblock.s_fsize) { fprintf("%l bad; i=%l(%s)\n", i, ino, s); return(1); } n = ldiv(0, i, 16); b = lrem(0, i, 16); if (lflg==0) { if(bmap[n] & (1<0) { bread(i, buf); for(n=0; n<256; n=+8) { if(df <= 0) break; df--; if((b=buf[n]) == 0) continue; if (lflg) if(!(buf[n].name[0]=='.' && (buf[n].name[1]=='\0' || (buf[n].name[1]=='.' && buf[n].name[2]=='\0')))) { if (--nnf<0) { nnf = 100; edn = sbrk(6*101); } edn->pnum = ino; edn->inum = buf[n]; edn->nptr = lfptr; for (j=0; j<14; j++) if(buf[n].name[j] == '\0') break; j++; write(lfdes, buf[n].name, j); lfptr =+ j; edn++; } for(j=0; j16*sblock.s_isize) { fprintf("%l din; i=%l(%s)\n", i, ino, s); continue; } if (!lflg) icnt->icnt[b-1]--; } } return(0); } pfilename(dp, recur) struct fname *dp; { struct fname *p; char name[14]; if (++recur > 10) printf("..."); else if (dp->pnum != 1) { for (p = dn; pinum==dp->pnum && p->pnum!=0) { pfilename(p, recur); goto yes; } } printf("???"); yes: printf("/"); } seek(lfdes, dp->nptr, 0); read(lfdes, name, 14); printf("%.14s", name); } alloc() { int b, i, buf[256]; i = --sblock.s_nfree; if(i<0 || i>=100) { fprintf("bad freeblock\n"); return(0); } b = sblock.s_free[i]; if(b == 0) return(0); if(sblock.s_nfree <= 0) { bread(b, buf); sblock.s_nfree = buf[0]; for(i=0; i<100; i++) sblock.s_free[i] = buf[i+1]; } return(b); } bread(bno, buf) { seek(fi, bno, 3); if(read(fi, buf, 512) != 512) { fprintf("read error %d\n", bno); exit(); } } free(in) { int i; int buf[256]; if(sblock.s_nfree >= 100) { buf[0] = sblock.s_nfree; for(i=0; i<100; i++) buf[i+1] = sblock.s_free[i]; sblock.s_nfree = 0; bwrite(in, buf); } sblock.s_free[sblock.s_nfree++] = in; } bwrite(bno, buf) { seek(fi, bno, 3); if(write(fi, buf, 512) != 512) { fprintf("write error %d\n", bno); exit(); } } number(s) char *s; { int n, c; n = 0; while(c = *s++) { if(c<'0' || c>'9') continue; n = n*10+c-'0'; } return(n); } fprintf(a, b, c, d, e) { printf(a, b, c, d, e); flush(); } if(sblock.s_nfree >= 100) { buf[0] = sblock.s_nfree; for(main(argc, argv) char **argv; { register i, m; register char *c; int count; if(argc < 3) { printf("arg count\n"); exit(1); } c = argv[1]; m = 0; for(m=0; *c; c++) { if(*c < '0' || *c > '7') { printf("bad mode\n"); exit(1); } m = (m<<3) | *c - '0'; } for(i=2; i= 100) { buf[0] = sblock.s_nfree; for(/ chown -- change owner .globl fopen, getc, mesg mov sp,r5 mov (r5),r4 cmp r4,$3 bge 1f jsr r5,mesg; ; .even 1: add $4,r5 mov (r5),r3 cmpb (r3),$'0 blt 1f cmpb (r3),$'9 bgt 1f jsr r5,cvnum; geta br do 1: mov $uids,r0 jsr r5,fopen; ubuf bec 1f jsr r5,mesg; ; .even sys exit 1: mov r3,r2 2: jsr r5,getc; ubuf bcc 3f who: jsr r5,mesg; ; .even sys exit 3: cmp r0,$': beq 3f cmpb (r2)+,r0 beq 2b 2: jsr r5,getc; ubuf bcs who cmp r0,$'\n bne 2b br 1b 3: tstb (r2) bne 2b 3: jsr r5,getc; ubuf cmpb r0,$': bne 3b jsr r5,cvnum; getc do: sub $2,r4 mov r1,0f+2 tst (r5)+ 1: mov (r5)+,0f sys chown; 0:..; 0 bec 2f mov 0b,r0 mov r0,0f clr 0f+2 3: tstb (r0)+ beq 3f inc 0f+2 br 3b 3: mov $1,r0 sys write; 0:..; .. jsr r5,mesg; ; .even 2: dec r4 bgt 1b sys exit cvnum: clr r1 1: jsr r5,*(r5); ubuf bcs 1f sub $'0,r0 cmp r0,$9. bhi 1f mpy $10.,r1 add r0,r1 br 1b 1: tst (r5)+ rts r5 geta: movb (r3)+,r0 tst (r5)+ rts r5 uids: .bss ubuf: .=.+518. buf cmpb r0,$': bne 3b jsr r5,cvnum; getc do: sub $2,r4 mov r1,0f+2 tst (r5)+ 1: mov (r5)+,0f sys chown; 0:..; 0 bec 2f mov 0b,r0 mov r0,0f clr 0f+2 3: tstb (r0)+ beq 3f inc 0f+2 br 3b 3: mov $1,r0 sys write; 0:..; .. jsr r5,mesg; ; .even 2: dec r4 bgt 1b sys exit cvnum: clr r1 1: jsr r5,*(r5); ubuf bcs 1f sub $'0,r0 cmp r0,$9. bhi 1f mpy $10.,r1 add r0,r1 br 1b 1: tst (r5)+ rts r5 geta: movb (r3)+,/ clri -- clear inode cmp (sp)+,$2 blt error beq 1f mov 4(sp),fs1 mov 4(sp),fs2 1: tst (sp)+ mov (sp)+,r0 clr r5 1: movb (r0)+,r1 beq 1f mpy $10.,r5 sub $'0,r1 cmp r1,$10. bhis error add r1,r5 br 1b 1: add $31.,r5 mov r5,r0 als $-4,r0 mov r0,0f sys open; fs1: filsys; 0 bes error mov r0,-(sp) sys seek; 0:..; 3 mov (sp),r0 sys read; buf; 512. mov (sp)+,r0 sys close mov r5,r0 als $5,r0 bic $!777,r0 add $buf,r0 mov $16.,r5 1: clr (r0)+ sob r5,1b sys open; fs2: filsys; 1 bes error mov r0,-(sp) mov 0b,0f sys seek; 0:..; 3 mov (sp)+,r0 sys write; buf; 512. bes error sys exit error: mov $1,r0 sys write; 1f; 2f-1f sys exit 1: 2: filsys: .even .bss buf: .=.+512. 31.,r5 mov r5,r0 als $-4,r0 mov r0,0f sys open; fs1: filsys; 0 bes error mov r0,-(sp) sys seek; 0:..; 3 mov (sp),r0 sys read; buf; 512. mov (sp)+,r0 sys close mov r5,r0 als $5,r0 bic $!777,r0 add $buf,r0 mov $16.,r5 1: clr (r0)+ sob r5,1b sys open; fs2: filsys; 1 bes/* copyright 1972 Bell Telephone Laboratories Inc. */ /* MOD 2.18 - UNIX SUPPORT GROUP **/ int ibuf1[259]; int ibuf2[259]; int eflg; int lflg 1; int line[2] {0, 1}; int chr[2] { -1, -1}; main(argc, argv) char **argv; { register c1, c2; char *arg; if(argc < 3) goto narg; arg = argv[1]; if(arg[0] == '-' && arg[1] == 's') { lflg--; argv++; argc--; } arg = argv[1]; if(arg[0] == '-' && arg[1] == 'l') { lflg++; argv++; argc--; } if(argc < 3) goto narg; arg = argv[1]; if(fopen(arg, ibuf1) < 0) goto barg; arg = argv[2]; if(fopen(arg, ibuf2) < 0) goto barg; loop: if (++chr[1]==0) chr[0]++; c1 = getc(ibuf1); c2 = getc(ibuf2); if(c1 == c2) { if (c1 == '\n') if (++line[1]==0) line[0]++; if(c1 == -1) { if(eflg) exit(1); exit(0); } goto loop; } if(lflg == 0) exit(1); if(c1 == -1) { arg = argv[1]; goto earg; } if(c2 == -1) goto earg; if(lflg == 1) { printf("%s %s differ: char %s, line ", argv[1], arg, locv(chr[0], chr[1])); printf("%s\n", locv(line[0], line[1])); exit(1); } eflg = 1; printf("%5s %3o %3o\n", locv(chr[0], chr[1]), c1, c2); goto loop; narg: printf("arg count\n"); exit(2); barg: printf("cannot open %s\n", arg); exit(2); earg: printf("EOF on %s\n", arg); exit(1); } putchar(c) { write(1, &c, 1); } } if(lflg == 0) exit(1); if(c1 == -1) { arg = argv[1]; goto earg; } if(c2 == -1) goto earg; if(lflg == 1) { printf("%s %s differ: char %s, line ", argv[1], arg, locv(chr[0], chr[1])); printf(# define PL 102 # define ESC 033 # define SI 017 # define SO 016 # define LINELN 800 char *page[PL]; char lbuff [LINELN], *line; main () { int c, i, j, ll, cp, mustwr; extern int fin, fout; fin = dup(0); fout = dup(1); for (ll=0; ll0) switch (c = getchar()) { case '\n': store (ll%PL); if (++ll >= mustwr) if (page[ll%PL] != 0) { printf ("%s\n",page[ll%PL]); mustwr++; free (page[ll%PL]);  page[ll%PL]=0; } fetch (ll%PL); cp = 0; continue; case '\0': continue; case ESC: c = getchar(); if (c == '7') { store(ll%PL); ll--; fetch (ll%PL); } else { outc (ESC, &line); outc (c, &line ); } continue; case '\r': line = lbuff; continue; case '\t': outc (' ', &line); cp = line-lbuff; while (cp++%8) outc(' ', &line); continue; default: outc(c, &line); } for (i=0; i0 || *(*lp) == '\b' || *(*lp) == ESC || **lp == SI || **lp == SO) { switch (*(*lp)) { case '\b': j++; (*lp)++; break; case '\0': *(*lp)++ = ' '; j--; break; case ESC: /* 'escape' */ (*lp) =+ 2; break; case SI: case SO: (*lp)++; break; default: (*lp)++; j--; break; } } if (c != ' ' || *(*lp) == '\0') *(*lp) = c; (*lp)++; } store (ll) { if (page[ll] != 0) free (page[ll]); page[ll] = alloc ( leng (lbuff) + 2); copy (page[ll],lbuff); } fetch(ll) { int i; for (i=0; i < LINELN; i++) lbuff[i] = '\0'; copy (line=lbuff, page[ll]); } copy (s,t) char *s, *t; { if (t == 0) return (*s=0); while (*s++ = *t++); } leng (s) char *s; { int l; for (l=0; s[l]; l++); return (l); } 2; break; case SI: case SO: (*lp)++; break; default: (*lp)++; j--; break; } } if (c != ' ' || *(*lp) == '\0') *(*lp) = c; (*lp)++; } store (ll) { if (page[llint one; int two; int three; char *ldr[3] {"", "\t", "\t\t" }; char ib1[518]; char ib2[518]; main(argc,argv) char *argv[]; { extern fout; int l; char lb1[80],lb2[80]; if(argc > 1) { if(*argv[1] == '-') { l = 1; while(*++argv[1]) { switch(*argv[1]) { case'1': if(!one) { one = 1; ldr[1][0] = ldr[2][l--] = '\0'; } break; case '2': if(!two) { two = 1; ldr[2][l--] = '\0'; } break; case '3': three = 1; break; default: printf("Illegal flag: %c\n",*argv[1]); exit(); } } argv++; argc--; } } if(argc < 3) { printf("Argc = %d\n",argc); exit(); } if(fopen(argv[1],ib1) < 0) { printf("Can't open %s\n",argv[1]); exit(); } if(fopen(argv[2],ib2) < 0) { printf("Can't open %s\n",argv[2]); exit(); } if(argc >= 4) { if((fout = creat(argv[3],0666)) < 0) { printf("Can't creat %s\n",argv[3]); exit(); } } if(rd(ib1,lb1) < 0) { if(rd(ib2,lb2) < 0) exit(); copy(ib2,lb2,2); } if(rd(ib2,lb2) < 0) copy(ib1,lb1,1); while(1) { switch(compare(lb1,lb2)) { case 0: wr(lb1,3); if(rd(ib1,lb1) < 0) { if(rd(ib2,lb2) < 0) fexit(); copy(ib2,lb2,2); } if(rd(ib2,lb2) < 0) copy(ib1,lb1,1); continue; case 1: wr(lb1,1); if(rd(ib1,lb1) < 0) copy(ib2,lb2,2); continue; case 2: wr(lb2,2); if(rd(ib2,lb2) < 0) copy(ib1,lb1,1); continue; } } } rd(file,buf) char *buf; { buf--; while((*++buf = getc(file)) >= 0) if(*buf == '\n') { *buf = '\0'; return(0); } return(-1); } wr(str,n) char *str; { switch(n) { case 1: if(one) return; break; case 2: if(two) return; break; case 3: if(three) return; } printf("%s%s\n",ldr[n-1],str); } copy(ibuf,lbuf,n) { do { wr(lbuf,n); } while(rd(ibuf,lbuf) >= 0); flush(); exit(); } compare(a,b) char *a,*b; { register char *ra,*rb; ra = --a; rb = --b; while(*++ra == *++rb) if(*ra == '\0') return(0); if(*ra < *rb) return(1); return(2); } fexit() { flush(); exit(); } return(0); } return(-1); } wr(str,n) char *str; { switch(n) { case 1: if(one) return; break; case 2: if(two) return; break; case 3: if(three) return; } printf("%s%s\n",ldr[n-1],str); } copy(ibuf,lbuf,n) { do { wr(lbuf,n); } while(rd(ibuf,lbuf) >= 0); flush(); exit(); } compare(a,b) char *a,*b; { register char *ra,*rb; ra = --a; rb = --b; while(*++ra == *++rb) if(*ra == '\0') return(0); if(*ra < *rb) return(1); return(2)/* * cp oldfile newfile */ main(argc,argv) char **argv; { int buf[256]; int fold, fnew, n, ct, tell; char *p1, *p2, *bp; int mode; tell = 0; if(argc == 4 && argv[1][0] == '-' && argv[1][1] == 't') { argc--; argv++; tell = 1; } if(argc != 3) { write(1, "Usage: cp oldfile newfile\n", 26); exit(8); } if((fold = open(argv[1], 0)) < 0) { write(1, "Cannot open old file.\n", 22); exit(8); } fstat(fold, buf); mode = buf[2]; /* Is destination a directory? */ if (stat(argv[2], buf+50)>=0 && (buf[52]&060000)==040000) { p1 = argv[1]; p2 = argv[2]; bp = buf+100; while(*bp++ = *p2++); bp[-1] = '/'; p2 = bp; while(*bp = *p1++) if(*bp++ == '/') bp = p2; argv[2] = buf+100; } if (stat(argv[2], buf+50) >= 0) { if (buf[0]==buf[50] && buf[1]==buf[51]) { write(1, "Copying file to itself.\n", 24); exit(8); } } if ((fnew = creat(argv[2], mode)) < 0) { write(1, "Can't create new file.\n", 23); exit(8); } while(n = read(fold, buf, 512)) { if(n < 0) { write(1, "Read error\n", 11); exit(8); } else if(write(fnew, buf, n) != n){ write(1, "Write error.\n", 13); exit(8); } ct++; } if(tell) { conf(ct, 6, buf); buf[3] = '\n'; write(1, buf, 7); } exit(0); } conf(n,width,buf) char *buf; { auto i,a; i = width; while(i--) buf[i] = ' '; buf[(a = n/10)?conf(a,--width,buf):--width] = n%10 + '0'; return(++width); } < 0) { write(1, "Can't create new file.\n", 23); exit(8); } while(n = read(fold, buf, 512)) { if(n < 0) { writeint timbuf[2]; char *cbp; char *tzname[2]; int dmsize[]; char cbuf[]; char *cbp; struct { char name[8]; char ln[2]; int wtime[2]; int pid; } wtmp[2]; main(argc, argv) int argc, **argv; { register char *tzn; register int i; extern int timezone, *localtime(); int wf; if(argc > 1) { cbp = argv[1]; if(gtime()) { write(1, "bad conversion\n", 15); exit(); } /* convert to Greenwich time, on assumption of Standard time. */ dpadd(timbuf, timezone); /* Now fix up to local daylight time. */ if (localtime(timbuf)[8]) dpadd(timbuf, -1*60*60); time(wtmp[0].wtime); for (i=0; wtmp[0].name[i]="OLDTIME"[i]; i++); wtmp[0].ln[0] = 'O'; wtmp[0].ln[1] = 'T'; if(stime(timbuf) < 0){ write(1, "no permission\n", 14); exit(); } if ((wf = open("/etc/wtmp", 1)) >= 0) { time(wtmp[1].wtime); for (i=0; wtmp[1].name[i]="NEWTIME"[i]; i++); wtmp[1].ln[0] = 'N'; wtmp[1].ln[1] = 'T'; seek(wf, 0, 2); write(wf, wtmp, 32); } } time(timbuf); cbp = cbuf; ctime(timbuf); write(1, cbuf, 20); tzn = tzname[localtime(timbuf)[8]]; if (tzn) write(1, tzn, 3); write(1, cbuf+19, 6); } gtime() { register int i; register int y, t; int d, h, m; extern int *localtime(); int nt[2]; t = gpair(); if(t<1 || t>12) goto bad; d = gpair(); if(d<1 || d>31) goto bad; h = gpair(); if(h == 24) { h = 0; d++; } m = gpair(); if(m<0 || m>59) goto bad; y = gpair(); if (y<0) { time(nt); y = localtime(nt)[5]; } if (*cbp == 'p') h =+ 12; if (h<0 || h>23) goto bad; timbuf[0] = 0; timbuf[1] = 0; y =+ 1900; for(i=1970; i100) return(-1); if(*cp == 0) return(-1); if ((d = *cp++ - '0') < 0 || d > 9) return(-1); cbp = cp; return (c+d); } gmdadd(60, 0); return(0); bad: return(1); } gdadd(n) { register char *t; t = timbuf[1]+n; if(t < timbuf[1]) timbuf[0]++; timbuf[1] = t; } gmdadd(m, n) { register int t1; timbuf[0] =* m; t1 = timbuf[1]; while(--m) gdadd(t1); gdadd(n); } gpair() { register int c, d; re#define LCASE 01 #define UCASE 02 int cflag; int fflag; int skip; int count; char *string; char *ifile; char *ofile; char *ibuf; char *obuf; char *ibs 512; char *obs 512; char *bs; char *cbs; char *ibc; char *obc; char *cbc; int nifr; int nipr; int nofr; int nopr; int ntrunc; int ibf; int obf; char *op; int nspace; char etoa[] { 0000,0001,0002,0003,0234,0011,0206,0177, 0227,0215,0216,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0235,0205,0010,0207, 0030,0031,0222,0217,0034,0035,0036,0037, 0200,0201,0202,0203,0204,0012,0027,0033, 0210,0211,0212,0213,0214,0005,0006,0007, 0220,0221,0026,0223,0224,0225,0226,0004, 0230,0231,0232,0233,0024,0025,0236,0032, 0040,0240,0241,0242,0243,0244,0245,0246, 0247,0250,0133,0056,0074,0050,0053,0041, 0046,0251,0252,0253,0254,0255,0256,0257, 0260,0261,0135,0044,0052,0051,0073,0136, 0055,0057,0262,0263,0264,0265,0266,0267, 0270,0271,0174,0054,0045,0137,0076,0077, 0272,0273,0274,0275,0276,0277,0300,0301, 0302,0140,0072,0043,0100,0047,0075,0042, 0303,0141,0142,0143,0144,0145,0146,0147, 0150,0151,0304,0305,0306,0307,0310,0311, 0312,0152,0153,0154,0155,0156,0157,0160, 0161,0162,0313,0314,0315,0316,0317,0320, 0321,0176,0163,0164,0165,0166,0167,0170, 0171,0172,0322,0323,0324,0325,0326,0327, 0330,0331,0332,0333,0334,0335,0336,0337, 0340,0341,0342,0343,0344,0345,0346,0347, 0173,0101,0102,0103,0104,0105,0106,0107, 0110,0111,0350,0351,0352,0353,0354,0355, 0175,0112,0113,0114,0115,0116,0117,0120, 0121,0122,0356,0357,0360,0361,0362,0363, 0134,0237,0123,0124,0125,0126,0127,0130, 0131,0132,0364,0365,0366,0367,0370,0371, 0060,0061,0062,0063,0064,0065,0066,0067, 0070,0071,0372,0373,0374,0375,0376,0377, }; char atoe[] { 0000,0001,0002,0003,0067,0055,0056,0057, 0026,0005,0045,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0074,0075,0062,0046, 0030,0031,0077,0047,0034,0035,0036,0037, 0100,0117,0177,0173,0133,0154,0120,0175, 0115,0135,0134,0116,0153,0140,0113,0141, 0360,0361,0362,0363,0364,0365,0366,0367, 0370,0371,0172,0136,0114,0176,0156,0157, 0174,0301,0302,0303,0304,0305,0306,0307, 0310,0311,0321,0322,0323,0324,0325,0326, 0327,0330,0331,0342,0343,0344,0345,0346, 0347,0350,0351,0112,0340,0132,0137,0155, 0171,0201,0202,0203,0204,0205,0206,0207, 0210,0211,0221,0222,0223,0224,0225,0226, 0227,0230,0231,0242,0243,0244,0245,0246, 0247,0250,0251,0300,0152,0320,0241,0007, 0040,0041,0042,0043,0044,0025,0006,0027, 0050,0051,0052,0053,0054,0011,0012,0033, 0060,0061,0032,0063,0064,0065,0066,0010, 0070,0071,0072,0073,0004,0024,0076,0341, 0101,0102,0103,0104,0105,0106,0107,0110, 0111,0121,0122,0123,0124,0125,0126,0127, 0130,0131,0142,0143,0144,0145,0146,0147, 0150,0151,0160,0161,0162,0163,0164,0165, 0166,0167,0170,0200,0212,0213,0214,0215, 0216,0217,0220,0232,0233,0234,0235,0236, 0237,0240,0252,0253,0254,0255,0256,0257, 0260,0261,0262,0263,0264,0265,0266,0267, 0270,0271,0272,0273,0274,0275,0276,0277, 0312,0313,0314,0315,0316,0317,0332,0333, 0334,0335,0336,0337,0352,0353,0354,0355, 0356,0357,0372,0373,0374,0375,0376,0377, }; extern fout; main(argc, argv) int argc; char **argv; { register (*conv)(); register char *ip; register c; int ebcdic(), ascii(), null(), cnull(), term(); fout = 2; conv = null; for(c=1; c= '0' && *cs <= '9') n = n*10 + *cs++ - '0'; for(;;) switch(*cs++) { case 'k': n =* 1024; continue; case 'w': n =* 2; continue; case 'b': n =* 512; continue; case '*': case 'x': string = cs; n =* number(); case '\0': return(n); } printf("not a number: %s\n", string); finish(); } cnull(cc) { register c; c = cc; if(cflag&UCASE && c>='a' && c<='z') c =+ 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c =+ 'a'-'A'; null(c); } null(c) { *op = c; op++; if(++obc >= obs) { flsh(); op = obuf; } } ascii(cc) { register c; c = 0; c =| etoa[cc]; if(cbs == 0) { cnull(c); return; } if(c == ' ') { nspace++; goto out; } while(nspace > 0) { null(' '); nspace--; } cnull(c); out: if(++cbc >= cbs) { null('\n'); cbc = 0; nspace = 0; } } ebcdic(cc) { register c; c = cc; if(cflag&UCASE && c>='a' && c<='z') c =+ 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c =+ 'a'-'A'; c = atoe[c] & 0377; if(cbs == 0) { null(c); return; } if(cc == '\n') { while(cbc < cbs) { null(atoe[' ']); cbc++; } cbc = 0; return; } if(cbc == cbs) ntrunc++; cbc++; if(cbc <= cbs) null(c); } term() { printf("%l+%l records in\n", nifr, nipr); printf("%l+%l records out\n", nofr, nopr); if(ntrunc) printf("%l truncated records\n", ntrunc); finish(); } finish() { flush(); exit(); } & c>='a' && c<='z') c =+ 'A'-'a'; if(cflag&LCASE && c>='A' && c<='Z') c =+ 'a'-'A'; c char *dargv[] { 0, "/dev/rk0", "/dev/rp0", 0 }; struct { char *s_isize; char *s_fsize; int s_nfree; int s_free[100]; int s_ninode; int s_inode[100]; char s_flock; char s_ilock; char s_fmod; int time[2]; int pad[50]; } sblock; int fi; main(argc, argv) char **argv; { int i; if(argc <= 1) { for(argc = 1; dargv[argc]; argc++); argv = dargv; } for(i=1; i 1) printf("%s ", argv[i]); dfree(argv[i]); } } dfree(file) char *file; { int i; fi = open(file, 0); if(fi < 0) { printf("cannot open %s\n", file); return; } sync(); bread(1, &sblock); i = 0; while(alloc()) i++; printf("%l\n", i); close(fi); } alloc() { int b, i, buf[256]; i = --sblock.s_nfree; if(i<0 || i>=100) { printf("bad free count\n"); return(0); } b = sblock.s_free[i]; if(b == 0) return(0); if(b=sblock.s_fsize) { printf("bad free block (%l)\n", b); return(0); } if(sblock.s_nfree <= 0) { bread(b, buf); sblock.s_nfree = buf[0]; for(i=0; i<100; i++) sblock.s_free[i] = buf[i+1]; } return(b); } bread(bno, buf) { int n; extern errno; seek(fi, bno, 3); if((n=read(fi, buf, 512)) != 512) { printf("read error %d\n", bno); printf("count = %d; errno = %d\n", n, errno); exit(); } } nt\n"); return(0); } b = sblock.s_free[i]; if(b == 0) return(0); if(b=sblock.s_fsize) { printf("bad free block (%l)\n", b); return(0); } if(sblock.s_nfree <= 0) { bread(b, buf); sblock.s_nfree = buf[0]; for(i=0;/* * Concatenate files. * */ char ibuf[512]; char obuf[512]; main(argc, argv) char **argv; { register char *cpi, *cpo; register n; int ubf; int fi; int fflg; fflg = 0; ubf = 0; if(argc > 1) { cpi = argv[1]; if(*cpi++ == '-' && *cpi++ == 'u' && *cpi++ == '\0') { argv++; argc--; ubf++; } } if (argc<2) { argc = 2; fflg++; } cpo = obuf; while (--argc > 0) { if ((*++argv)[0]=='-' && (*argv)[1]=='\0' || fflg) fi = 0; else { if ((fi = open(*argv, 0)) < 0) { error(*argv); continue; } } while ((n = read(fi, ibuf, 512)) > 0) { if(ubf) { write(1, ibuf, n); continue; } cpi = ibuf; do { if (cpo >= &obuf[512]) { write(1, obuf, 512); cpo = obuf; } *cpo++ = *cpi++; } while (--n); } if (fi>0) close(fi); } if (cpo > obuf) write(1, obuf, cpo-obuf); exit(0); } error(s) { register char *cp; write(2, "cat: can't open ", 16); cp = s; while (*cp) { write(2, cp, 1); cp++; } write(2, "\n", 1); } errorchar buf[100]; int stat; main(argc, argv) char **argv; { register i; register char *c1, *c2; if(argc < 3) { write(2, "arg count\n", 10); exit(1); } argc--; c1 = buf; c2 = argv[argc]; while(*c1++ = *c2++); c1[-1] = '/'; *c1++ = '.'; *c1 = '\0'; for(i=1; i=0; j =- 5){ execv(&cmd[j],as); if(errno == ENOEXEC) goto runcom; if(errno != ENOENT) return(errno); } return(errno); runcom: sargs[1] = &cmd[j]; sargs[0] = "sh"; i = 1; while(as[i] != 0) { if(i>99) return(E2BIG); sargs[i+1] = as[i]; i++; } sargs[i+1] = 0; execv("/bin/sh",sargs); return(-1); } ]; register i,j; extern errno; char *sargs[101]; j = 0; for(i=0;i<10;i++) cmd[i] = "/usr//bin/"[i]; while(i<100 && as[0][j]) cmd[i++] = as[0][j++]; cmd[i++] = 0; for(j=10;j>=0; j =- 5){ execv(&cmd[j],as); if(errno == ENOEXEC) goto runcom; if(errno != ENOENT) return(errno); } return(errno); runcom:/ dsw - delete from tty cmp (sp)+,$2 blt 1f tst (sp)+ mov (sp)+,0f 1: sys stat; 0:dot; stbuf bes error mov stbuf+4,r0 bic $!60000,r0 cmp r0,$40000 bne error mov 0b,0f sys open; 0:..; 0 bes error mov r0,r1 1: clrb buf+17. mov r1,r0 sys read; buf; 16. bes done tst r0 beq done tst buf beq 1b mov 0b,r2 mov $obuf,r3 2: movb (r2)+,(r3)+ bne 2b mov $buf+2,r2 dec r3 cmpb -1(r3),$'/ beq 2f movb $'/,(r3)+ 2: movb (r2)+,(r3)+ bne 2b sys stat; obuf; stbuf bes error bit $60000,stbuf+4 bne 1b mov $buf+2,r2 2: tstb (r2)+ bne 2b movb $' ,-(r2) sub $buf+1,r2 mov r2,0f 2: mov $1,r0 sys write; buf+2; 0:.. clr r0 sys read; ch; 1 cmpb ch,$'\n beq 1b clr r0 sys read; ch1; 1 cmpb ch1,$'\n beq 3f 4: clr r0 sys read; ch; 1 cmpb ch,$'\n beq 2b br 4b 3: cmpb ch,$'x beq done cmpb ch,$'y bne 2b sys unlink; obuf bes error br 1b done: sys exit error: mov $1,r0 sys write; mes; 2 sys exit dot: <.\0> mes: .bss obuf: .=.+100. stbuf: .=.+40. buf: .=.+18. ch: .=.+1 ch1: .=.+1 v $buf+2,r2 2: tstb (r2)+ bne 2b movb $' ,-(r2) sub $buf+1,r2 mov r2,0f 2: mov $1,r0 sys write; buf+2; 0:.. clr r0 sys read; ch; 1 cmpb ch,$'\n beq 1b clr r0 sys read; ch1; 1 cmpb ch1,$'\n beq 3f 4: clr r0 sys read; ch; 1 cmpb ch,$'\n beq 2b br 4b 3: cmpb ch,$'x beq done cmpb ch,$'y bne 2b sys unlink; obuf bes error br 1b done: sys exit error: mov $1,r0 sys write; mes; 2 sys exit dot: <.\0> mes: .bss obuf: .=.+100. stbuf: .=.+40. buf: .=.+18. ch: .=.+1/ dusg -- summarize disk usage .globl putc, flush, _end mov $1,obuf mov (sp)+,r5 tst (sp)+ 1: dec r5 bgt 2f tstb buf1 beq 3f jsr r5,flush; obuf sys exit 3: mov $dot,r0 br 3f 2: mov (sp)+,r0 3: cmpb (r0),$'- bne 2f cmpb 1(r0),$'a bne 3f inc aflg br 1b 3: cmpb 1(r0),$'s bne 1b dec aflg br 1b 2: mov $buf1,r1 2: movb (r0)+,(r1)+ bne 2b dec r1 clr buf3+10. mov $_end,iptr mov $_end,brk sys break; _end jsr pc,tree tst aflg bpl 1b jsr r5,name br 1b tree: sys stat; buf1; buf2 bes 1f bic $!60000,buf2+4 bit $20000,buf2+4 beq 2f 1: clr r4 rts pc 2: mov $_end,r2 mov buf2+2,r3 1: cmp r2,iptr bhis 1f cmp r3,(r2)+ bne 1b clr r4 jsr r5,cname rts pc 1: cmp r2,brk blo 1f add $512.,brk sys break; brk: .. 1: mov r3,(r2)+ mov r2,iptr cmp $40000,buf2+4 beq 1f jsr pc,gsize jsr r5,cname rts pc 1: jsr pc,gsize mov r4,r3 sys open; buf1; 0 bec 1f rts pc 1: mov r0,-(sp) mov r1,-(sp) 1: mov 2(sp),r0 sys read; buf3; 16. bes 1f tst r0 beq 1f tst buf3 beq 1b cmp buf3+2,$".\0 beq 1b cmp buf3+2,$".. bne 2f tst buf3+4 beq 1b 2: mov $buf3+2,r2 mov (sp),r1 movb $'/,(r1)+ cmpb -2(r1),$'/ bne 2f dec r1 2: movb (r2)+,(r1)+ bne 2b dec r1 mov r3,-(sp) jsr pc,tree mov r4,r3 add (sp)+,r3 br 1b 1: mov (sp)+,r1 clrb (r1) mov (sp)+,r0 sys close mov r3,r4 tst aflg bmi 1f jsr r5,name 1: rts pc cname: tst aflg bgt name rts r5 name: jsr pc,pnum mov $011,r0 jsr pc,pchar mov $buf1,r2 1: movb (r2)+,r0 beq 1f jsr pc,pchar br 1b 1: mov $'\n,r0 jsr pc,pchar rts r5 gsize: mov r5,-(sp) mov buf2+10.,r5 / size movb buf2+9.,r4 add $511.,r5 adc r4 alsc $-9,r4 cmp r5,$8. blo 1f mov r5,-(sp) add $255.,r5 alsc $-8,r4 add (sp)+,r5 1: mov r5,r4 mov (sp)+,r5 rts pc pnum: mov r4,-(sp) mov r5,-(sp) mov r4,r5 jsr pc,1f mov (sp)+,r5 mov (sp)+,r4 rts pc 1: clr r4 dvd $10.,r4 mov r5,-(sp) mov r4,r5 beq 1f jsr pc,1b 1: mov (sp)+,r0 add $'0,r0 jsr pc,pchar rts pc pchar: jsr r5,putc; obuf rts pc dot: <.\0> .bss iptr: .=.+2 buf1: .=.+100. buf2: .=.+40. buf3: .=.+18. aflg: .=.+2 obuf: .=.+520. movb buf2+9.,r4 add $511.,r5 adc r4 alsc $-9,r4 cmp r5,$8. blo 1f mov r5,-(sp) add $255.,r5 alsc $-8,r4 add (sp)+,r5 1: mov r5,r4 mov (sp)+,r5 rts pc pnum: mov r4,-(sp) mov r5,-(sp) mov r4,r5 jsr pc,1f mov (sp)+,r5 mov (sp)+,r4 rts pc 1: clr r4 dvd $10.,r4 mov r5,-(sp) mov r4,r5 beq 1f jsr pc,1b 1: mov (sp)+,r0 add $'0,r0 jsr pc,pchar rts pc pchar: jsr r5,putc; obuf rts pc dot: <.\0> .bss iptr: .=.+2 buf1:# /* * incremental dump * dump fisbuodh filesystem * f take output tape from arglist * i from date in /etc/dtab * s specify tape size in feet * b specify tape size in blocks * u update /etc/dtab to current date * 0 dump from the epoch * d dump specified number of days * h dump specified number of hours * a on incremental dump, dump files even >= MAXSIZE * p old format 512 byte records * n new format specify blocks per record * q quick format 1600 bpi */ char *dargv[] { 0, "i", "/dev/rp0", 0 }; #include "../head/ino.h" #include "../head/filsys.h" #define MAXSIZE 1000 struct filsys sblock; struct { char name[16]; int date[2]; } dtab[10]; char *dfile "/etc/dtab"; char *ofile "/dev/rmt0"; /* defalt output */ char *qfile "/dev/rmt2"; /* 1600 bpi output */ char *pfile "/dev/mt0"; /* buffered output */ int *talist; int fi; int *bigbuf; int bufsize; int inum; int buf[256]; int dbuf[256]; int ibuf[256]; int vbuf[256]; char *date[2]; char *ddate[2]; char *barg; char *sarg; char *narg; int fo -1; int pher; int dflg; int iflg; int cflg; int aflg; int bflg; int sflg; int pflg; int nflg; int qflg; int recsiz; char *tsize; char *taddr; main(argc, argv) char **argv; { char *key; int s, i, nfil, nblk, f; register *tap; register struct inode *ip; int ino; long n; time(date); if(argc == 1) { argv = dargv; for(argc = 1; dargv[argc]; argc++); } argc--; argv++; key = *argv; while(*key) switch(*key++) { default: printf("bad character in key\n"); exit(0); case 'a': /* dump all (even large) */ aflg++; continue; case '-': continue; case 'c': /* increment file name */ cflg++; continue; case 'f': /* file name from arg list */ argc--; argv++; qfile = *argv; ofile = qfile; continue; case 'i': /* date from date file */ iflg++; continue; case 's': /* tape size */ sarg = argv[1]; sflg++; argv++; argc--; continue; case 'b': /* tape size */ barg = argv[1]; bflg++; argv++; argc--; continue; case 'u': /* rewrite date */ dflg++; continue; case '0': /* dump all */ ddate[0] = ddate[1] = 0; continue; case 'd': /* dump some number of days */ i = 21600; goto sd; case 'h': /* dump some number of hours */ i = 900; goto sd; case 'p': /* dump 512 byte records */ pflg++; qfile = pfile; ofile = qfile; continue; case 'n': /* dump recsiz*512 byte records */ narg = argv[1]; nflg++; argv++; argc--; continue; case 'q': /* 1600 bpi */ ofile = qfile; qflg++; continue; sd: ddate[0] = date[0]; ddate[1] = date[1]; s = number(argv[1])*4; argv++; argc--; while(s) { if(i > ddate[1]) ddate[0]--; ddate[1] =- i; s--; } continue; } if(argc <= 1) { printf("no file system specified\n"); exit(0); } info(); bigbuf = sbrk(bufsize); if(bigbuf == -1){ printf("No memory\n"); exit(0); } if(iflg) { f = open(dfile, 0); if(f >= 0) { read(f, dtab, sizeof dtab); close(f); for(i=0; i<10; i++) if(equal(dtab[i].name, argv[1])) { ddate[0] = dtab[i].date[0]; ddate[1] = dtab[i].date[1]; } } } printf("%s:\n", argv[1]); fi = open(argv[1], 0); if(fi < 0) { printf("cannot open %s\n", argv[1]); exit(0); } printf("incremental dump from\n"); pdate(ddate); sync(); bread(1, &sblock); talist = sbrk(size(0, sblock.s_isize*32)*512); tap = talist; if(tap == -1) { printf("No memory\n"); exit(0); } nfil = 0; nblk = size(0, sblock.s_isize*32); n = nblk; ino = 0; for(i=0; ii_mode == 0 || ip->i_nlink == 0) { *tap++ = -1; continue; } if(ip->i_mtime[0] < ddate[0]) goto no; if(ip->i_mtime[0] == ddate[0] && ip->i_mtime[1] < ddate[1]) goto no; s = size(ip->i_size0&0377, ip->i_size1) + 1; if (s>MAXSIZE && aflg==0 && iflg!=0) { printf("%l big; not dumped.\n", ino); goto no; } nfil++; n =+ s; *tap++ = s; continue; no: *tap++ = 0; } } printf("%l files\n%D blocks\n", nfil, n); i = tsize; n = n*100l; i = (n/i)/recsiz; s = i%100; printf("%l.%l%l tapes\n", i/100, s/10, (s-(s/10)*10)); tap = buf; clrbuf(tap); *tap++ = sblock.s_isize; *tap++ = sblock.s_fsize; *tap++ = date[0]; *tap++ = date[1]; *tap++ = ddate[0]; *tap++ = ddate[1]; *tap++ = tsize; *tap++ = recsiz; swrite(buf); i = size(0, sblock.s_isize*32); tap = talist; while(i--) { bwrite(tap); tap =+ 256; } tap = talist; for(i=0; ii_mtime[2]) *p++ = *q++; swrite(dbuf); if(ip->i_mode & (IFBLK&IFCHR)) { if(sz != 0) printf("special\n"); return; } for(p = &ip->i_addr[0]; p < &ip->i_addr[8]; p++) if(*p) { if(ip->i_mode&ILARG) { bread(*p, ibuf); for(q = &ibuf[0]; q < &ibuf[256]; q++) if(*q) { /*this section dumps huge files*/ /*if(p == &ip->i_addr[7]) { bread(*q, vbuf); for(r = &vbuf[0]; r < &vbuf[256]; r++) if(*r) { if(--sz < 0) goto pe; bread(*r, dbuf); bwrite(dbuf); } continue; }*/ if(--sz < 0) goto pe; bread(*q, dbuf); bwrite(dbuf); } } else { if(--sz < 0) goto pe; bread(*p, dbuf); bwrite(dbuf); } } if(sz) goto pe; return; pe: clrbuf(dbuf); while(--sz >= 0) bwrite(dbuf); pher++; } bread(bno, b) { seek(fi, bno, 3); if(read(fi, b, 512) != 512) { printf("read error %l\n", bno); } } clrbuf(b) int *b; { register i, *p; p = b; i = 256; while(i--) *p++ = 0; } swrite(b) int *b; { register i, s, *p; i = 253; s = taddr + 1 + inum; p = b; while(i--) s =+ *p++; *p++ = inum; *p++ = taddr + 1; *p = 031415 - s; bwrite(b); } bwrite(b) { register *p,*g; int f,j; static int i; g = b; p = bigbuf + i*(256); for(j = 0;j < 256; j++) *p++ = *g++; if(++i == recsiz) { rawout(); i = 0; } } rawout() { static int nrec; int *ta ,*bi; if(taddr == 0) { if(fo != -1) { printf("change tapes\n"); close(fo); if(!cflg) rdline(); } otape(); } ta = taddr; bi = bigbuf; while(write(fo, bi, bufsize) != bufsize) { printf("write error\n"); printf("no. of records = %d\n",ta); rdline(); } taddr++; if(taddr >= tsize) taddr = 0; for(ta = bigbuf; ta < bigbuf + (bufsize/2); ta++) *ta = 0; } rdline() { char c; while(read(0,&c,1) != 0){ if(c == '\n') return; } exit(0); } number(s) char *s; { register n, c; n = 0; while(c = *s++) { if(c<'0' || c>'9') continue; n = n*10+c-'0'; } return(n); } size(s0, s1) { register s; extern ldivr; s = ldiv(s0&0377, s1, 512); if(ldivr) s++; return(s); } otape() { register char *p; fo = creat(ofile, 0666); if(fo < 0) { printf("can not open %s\n", ofile); exit(0); } if(!cflg) return; p = ofile; while(*p++) ; p[-2]++; } equal(a, b) char *a, *b; { while(*a++ == *b) if(*b++ == 0) return(1); return(0); } info() { int div, feet, i; char *bsize; long n; bufsize = 5120; feet = 2200; i = 64; if(pflg) bufsize = 512; else if(nflg) bufsize = 512*number(narg); if(sflg) feet = number(sarg); if(qflg && !pflg) i = 32; recsiz = bufsize/512; div = ((i*recsiz)+60)/10; if(tsize = (feet/div)*120); else tsize = 1; if(bflg){ n = number(barg); n = n & 0177777l; bsize = n/recsiz; if(bsize > tsize){ printf("too many blocks for this tape\n"); exit(0); } tsize = bsize; feet = (tsize/120)*div; } printf("tape size = %d records\n",tsize); printf("each record is %d blocks long\n",recsiz); printf("the tape must be longer than %d feet\n",feet); } ; if(sflg) feet = number(sarg); if(qflg && !pflg) i = 32; recsiz = bufsize/512; div = (# /* diff3 - 3-way differential file comparison*/ /* diff3 [-e] d13 d23 f1 f2 f3 * * d13 = diff report on f1 vs f3 * d23 = diff report on f2 vs f3 * f1, f2, f3 the 3 files */ struct range {int from,to; }; /* from is first in range of changed lines * to is last+1 * from=to=line after point of insertion * for added lines */ struct diff {struct range old, new;}; #define NC 200 /* the following declarations have the effect of * struct diff d13[NC], d23[NC], de[NC]; * but they succeed in overlaying de and d23 * de is used to gather editing scripts, * that are later spewed out in reverse order. * its first element must be all zero * the "new" component of de contains byte positions * in file 3 instead of line numbers */ struct diff d13[NC]; struct diff dz[NC+1]; struct diff *de dz; struct diff *d23 dz+1; char line[256]; int buf[3][259]; int linct[3] {0,0,0}; /* the number of the last-read line in each file * is kept in cline[0-2] */ int cline[3]; /* the latest known correspondence between line * numbers of the 3 files is stored in last[1-3] */ int last[4]; int eflag; int debug 0; main(argc,argv) char **argv; { register i,m,n; if(*argv[1]=='-') { switch(argv[1][1]) { default: eflag = 3; break; case '3': eflag = 2; break; case 'x': eflag = 1; } argv++; argc--; } if(argc<6) { printf("arg count\n"); exit(1); } m = readin(argv[1],d13); n = readin(argv[2],d23); for(i=0;i<=2;i++) if(fopen(argv[i+3],buf[i],0) <0) { printf("Can't open %s\n",argv[i+3]);  exit(1); } merge(m,n); } /*pick up the line numbers of allcahnges from * one change file * (this puts the numbers in a vector, which is not * strictly necessary, since the vector is processed * in one sequential pass. The vector could be optimized * out of existence) */ readin(name,dd) char *name; struct diff *dd; { register i; int a,b,c,d; char kind; char *p; fopen(name,buf[0],0); for(i=0;getchange(buf[0]);i++) { if(i>=NC) { write(2,"too many changes\n",17); exit(0); } p = line; a = b = number(&p); if(*p==',') { p++; b = number(&p); } kind = *p++; c = d = number(&p); if(*p==',') { p++; d = number(&p); } if(kind=='a') a++; if(kind=='d') c++; b++; d++; dd[i].old.from = a; dd[i].old.to = b; dd[i].new.from = c; dd[i].new.to = d; } dd[i].old.from = dd[i-1].old.to; dd[i].new.from = dd[i-1].new.to; close(buf[0][0]); return(i); } number(lc) char **lc; { register nn; nn = 0; while(digit(**lc)) nn = nn*10 + *(*lc)++ - '0'; return(nn); } digit(c) { return(c>='0'&c<='9'); } getchange(b) int *b; { while(getline(b)) if(digit(line[0])) return(1); return(0); } getline(b) int b[]; { register i; for(i=0;(line[i]=getc(b))!=-1;i++) if(line[i]=='\n') { line[++i] = 0; return(i); } return(0); } merge(m1,m2) { register struct diff *d1, *d2, *d3; int dup; int j; int t1,t2; d1 = d13; d2 = d23; j = 0; for(;(t1 = d1old.from,d1->old.to, d1->new.from,d1->new.to, d2->old.from,d2->old.to, d2->new.from,d2->new.to); } /* first file is different from others*/ if(!t2||t1&&d1->new.to < d2->new.from) { /* stuff peculiar to 1st file */ if(eflag==0) { separate("1"); change(1,&d1->old,0); keep(2,&d1->old,&d1->new); change(3,&d1->new,0); } d1++; continue; } /* second file is different from others*/ if(!t1||t2&&d2->new.to < d1->new.from) { if(eflag==0) { separate("2"); keep(1,&d2->old,&d2->new); change(2,&d2->old,0); change(3,&d2->new,0); } d2++; continue; } /* merge overlapping changes in first file * this happens after extension see below*/ if(d1+1new.to>=d1[1].new.from) { d1[1].old.from = d1->old.from; d1[1].new.from = d1->new.from; d1++; continue; } /* merge overlapping changes in second*/ if(d2+1new.to>=d2[1].new.from) { d2[1].old.from = d2->old.from; d2[1].new.from = d2->new.from; d2++;  continue; } /* stuff peculiar to third file or different in all*/ if(d1->new.from==d2->new.from&& d1->new.to==d2->new.to) { dup = duplicate(&d1->old,&d2->old); /* dup=0 means all files differ * dup =1 meands files 1&2 identical*/ if(eflag==0) { separate(dup?"3":""); change(1,&d1->old,dup); change(2,&d2->old,0); d3 = d1->old.to>d1->old.from?d1:d2; change(3,&d3->new,0); } else j = edit(d1,dup,j); d1++; d2++; continue; } /* overlapping changes from file1 & 2 * extend changes appropriately to * make them coincide*/ if(d1->new.fromnew.from) { d2->old.from =- d2->new.from-d1->new.from; d2->new.from = d1->new.from; } else if(d2->new.fromnew.from) { d1->old.from =- d1->new.from-d2->new.from; d1->new.from = d2->new.from; } if(d1->new.to >d2->new.to) { d2->old.to =+ d1->new.to - d2->new.to; d2->new.to = d1->new.to; } else if(d2->new.to >d1->new.to) { d1->old.to =+ d2->new.to - d1->new.to; d1->new.to = d2->new.to; } } if(eflag) edscript(j); } separate(s) char *s; { printf("====%s\n",s); } /* the range of ines rold.from thru rold.to in file i * is to be changed. it is to be printed only if * it does not duplicate something to be printed later */ change(i,rold,dup) struct range *rold; { printf("%d:",i); last[i] = rold->to; prange(rold); if(dup) return; if(debug) return; i--; skip(i,rold->from,0); skip(i,rold->to," "); } /* print the range of line numbers, rold.from thru rold.to  * as n1,n2 or n1 */ prange(rold) struct range *rold; { if(rold->to<=rold->from) printf("%da\n",rold->from-1); else { printf("%d",rold->from); if(rold->to > rold->from+1) printf(",%d",rold->to-1); printf("c\n"); } } /* no difference was reported by diff between file 1(or 2) * and file 3, and an artificial dummy difference (trange) * must be ginned up to correspond to the change reported * in the other file */ keep(i,rold,rnew) struct range *rold, *rnew; { register delta; struct range trange; delta = last[3] - last[i]; trange.from = rnew->from - delta; trange.to = rnew->to - delta; change(i,&trange,1); } /* skip to just befor line number from in file i * if "pr" is nonzero, print all skipped stuff * w with string pr as a prefix */ skip(i,from,pr) char *pr; { register j,n; for(n=0;cline[i]to-r1->from != r2->to-r2->from) return(0); skip(0,r1->from,0); skip(1,r2->from,0); nchar = 0; for(nline=0;nlineto-r1->from;nline++) { do { c = getc(buf[0]); d = getc(buf[1]); if(c== -1||d== -1) trouble(); nchar++; if(c!=d) { repos(nchar); return; } } while(c!= '\n'); } repos(nchar); return(1); } repos(nchar) { register i; for(i=0;i<2;i++) { seek(buf[i][0],-nchar-buf[i][1],1); buf[i][1] = 0; } } trouble() { write(2,"diff3 logic error\n",17); abort(); } /* collect an editing script for later regurgitation */ edit(diff,dup,j) struct diff *diff; { if(((dup+1)&eflag)==0) return(j); j++; de[j].old.from = diff->old.from; de[j].old.to = diff->old.to; de[j].new.from = de[j-1].new.to +skip(2,diff->new.from,0); de[j].new.to = de[j].new.from +skip(2,diff->new.to,0); return(j); } /* regurgitate */ edscript(n) { register j,k; for(n=n;n>0;n--) { prange(&de[n].old); seek(buf[2][0],de[n].new.from,0); for(k=de[n].new.to-de[n].new.from;k>0;k=- j) { j = k>512?512:k; if(read(buf[2][0],buf[0],j)!=j) trouble(); write(1,buf[0],j); } printf(".\n"); } } urn(j); j++; de[j].old.from = diff->old.from; de[j].old.to = diff->old.to; de[j].new.from = de[j-1].new.to +skip(2,diff->new.from,0); de[j].new.to = de[j].new.from +skip(2,diff->new.to,0); return(j); } /* regurgiif ! "(" $1 = -e -o $1 = -x -o $1 = -3 ")" goto diff = e $1 shift : diff diff $1 $3 >d3$$1 diff $2 $3 >d3$$2 /usr/lib/diff3 $e d3$$1 d3$$2 $1 $2 $3 rm d3$$1 d3$$2 j = k>512?512:k; if(read(buf[2][0],buf[0],j)!=j) trouble(); write(1,buf[0],j); } printf(".\n"); } } urn(j); j++; de[j].old.from = diff->old.from; de[j].old.to = diff->old.to; de[j].new.from = de[j-1].new.to +skip(2,diff->new.from,0); de[j].new.to = de[j].new.from +skip(2,diff->new.to,0); return(j); } /* regurgimain(argc, argv) int argc; char *argv[]; { register c; register char *i, **v; if((c = argc - 1) == 0) { write(1, "\n", 1); exit(0); } v = ++argv; do { for(i = *v++; *i++; ); --i; if(--c>0) *i++ = ' '; else { if(*--i != ' ') { i++; *i++ = '\n'; } write(1, *argv, i =- *argv); } } while(c>0); } ld.to = diff->old.to; de[j].new.from = de[j-1].new.to +skip(2,diff->new.from,0); de[j].new.to = de[j].new.from +skip(2,diff->new.to,0); return(j); } /* regurgi# /* * Editor */ #define SIGHUP 1 #define SIGINTR 2 #define SIGQUIT 3 #define SIGTERM 15 #define FNSIZE 64 #define LBSIZE 512 #define ESIZE 128 #define GBSIZE 256 #define NBRA 5 #define EOF -1 #define CBRA 1 #define CCHR 2 #define CDOT 4 #define CCL 6 #define NCCL 8 #define CDOL 10 #define CEOF 11 #define CKET 12 #define CBACK 14 #define STAR 01 #define error errfunc() #define READ 0 #define WRITE 1 int peekc; int lastc; char savedfile[FNSIZE]; char file[FNSIZE]; char linebuf[LBSIZE]; char rhsbuf[LBSIZE/2]; char expbuf[ESIZE+4]; int circfl; int *zero; int *dot; int *dol; int *endcore; int *fendcore; int *addr1; int *addr2; char genbuf[LBSIZE]; int count[2]; char *nextip; char *linebp; int ninbuf; int io; int pflag; int onhup; int onquit; int vflag 1; int listf; int col; char *globp; int tfile -1; int tline; char *tfname; char *loc1; char *loc2; char *locs; char ibuff[512]; int iblock -1; char obuff[512]; int oblock -1; int ichanged; int nleft; int errfunc(); int *errlab errfunc; char TMPERR[] "TMP"; char WRERR[] "WRITE ERROR"; int names[26]; int anymarks; char *braslist[NBRA]; char *braelist[NBRA]; int nbra; int subnewa; int subolda; int fchange; main(argc, argv) char **argv; { register char *p1, *p2; extern int onintr(), quit(); int oldintr; onquit = signal(SIGQUIT, 1); onhup = signal(SIGHUP, 1); oldintr = signal(SIGINTR, 1); if ((signal(SIGTERM, 1)&01) == 0) signal(SIGTERM, quit); argv++; if (argc > 1 && **argv=='-') { vflag = 0; /* allow debugging quits? */ if ((*argv)[1]=='q') {  signal(SIGQUIT, 0); vflag++; } argv++; argc--; } if (argc>1) { p1 = *argv; p2 = savedfile; while (*p2++ = *p1++); globp = "r"; } fendcore = sbrk(0); tfname = mktemp("/tmp/eXXXXX"); init(); if ((oldintr&01) == 0) signal(SIGINTR, onintr); setexit(); commands(); quit(); } commands() { int getfile(), gettty(); register *a1, c; for (;;) { if (pflag) { pflag = 0; addr1 = addr2 = dot; goto print; } addr1 = 0; addr2 = 0; do { addr1 = addr2; if ((a1 = address())==0) { c = getchar(); break; } addr2 = a1; if ((c=getchar()) == ';') { c = ','; dot = a1; } } while (c==','); if (addr1==0) addr1 = addr2; switch(c) { case 'a': setdot(); newline(); append(gettty, addr2); continue; case 'c': delete(); append(gettty, addr1-1); continue; case 'd': delete(); continue; case 'E': fchange = 0; c = 'e'; case 'e': setnoaddr(); if (vflag && fchange) { fchange = 0; error; } filename(c); init(); addr2 = zero; goto caseread; case 'f': setnoaddr(); filename(c); puts(savedfile); continue; case 'g': global(1); continue; case 'i': setdot(); nonzero(); newline(); append(gettty, addr2-1); continue; case 'k': if ((c = getchar()) < 'a' || c > 'z') error; newline(); setdot(); nonzero(); names[c-'a'] = *addr2 & ~01; anymarks =| 01; continue; case 'm': move(0); continue; case '\n': if (addr2==0) addr2 = dot+1; addr1 = addr2; goto print; case 'l': listf++; case 'p': newline(); print: setdot(); nonzero(); a1 = addr1; do puts(getline(*a1++)); while (a1 <= addr2); dot = addr2; listf = 0; continue; case 'Q': fchange = 0; case 'q': setnoaddr(); newline(); quit(); case 'r': filename(c); caseread: if ((io = open(file, 0)) < 0) { lastc = '\n'; error; } setall(); ninbuf = 0; c = zero != dol; append(getfile, addr2); exfile(); fchange = c; continue; case 's': setdot(); nonzero(); substitute(globp); continue; case 't': move(1); continue; case 'u': setdot(); nonzero(); newline(); if ((*addr2&~01) != subnewa) error; *addr2 = subolda; continue; case 'v': global(0); continue; case 'w': setall(); nonzero(); filename(c); if ((io = creat(file, 0666)) < 0) error; putfile(); exfile(); if (addr1==zero+1 && addr2==dol) fchange = 0; continue; case '=': setall(); newline(); count[1] = (addr2-zero)&077777; putd(); putchar('\n'); continue; case '!': unix(); continue; case EOF: return; } error; } } address() { register *a1, minus, c; int n, relerr; minus = 0; a1 = 0; for (;;) { c = getchar(); if ('0'<=c && c<='9') { n = 0; do { n =* 10; n =+ c - '0'; } while ((c = getchar())>='0' && c<='9'); peekc = c; if (a1==0) a1 = zero; if (minus<0) n = -n; a1 =+ n; minus = 0; continue; } relerr = 0; if (a1 || minus) relerr++; switch(c) { case ' ': case '\t': continue; case '+': minus++; if (a1==0) a1 = dot; continue; case '-': case '^': minus--; if (a1==0) a1 = dot; continue; case '?': case '/': compile(c); a1 = dot; for (;;) { if (c=='/') { a1++; if (a1 > dol) a1 = zero; } else { a1--; if (a1 < zero) a1 = dol; } if (execute(0, a1)) break; if (a1==dot) error; } break; case '$': a1 = dol; break; case '.': a1 = dot; break; case '\'': if ((c = getchar()) < 'a' || c > 'z') error; for (a1=zero; a1<=dol; a1++) if (names[c-'a'] == (*a1 & ~01)) break; break; default: peekc = c; if (a1==0) return(0); a1 =+ minus; if (a1dol) error; return(a1); } if (relerr) error; } } setdot() { if (addr2 == 0) addr1 = addr2 = dot; if (addr1 > addr2) error; } setall() { if (addr2==0) { addr1 = zero+1; addr2 = dol; if (dol==zero) addr1 = zero; } setdot(); } setnoaddr() { if (addr2) error; } nonzero() { if (addr1<=zero || addr2>dol) error; } newline() { register c; if ((c = getchar()) == '\n') return; if (c=='p' || c=='l') { pflag++; if (c=='l') listf++; if (getchar() == '\n') return; } error; } filename(comm) { register char *p1, *p2; register c; count[1] = 0; c = getchar(); if (c=='\n' || c==EOF) { p1 = savedfile; if (*p1==0 && comm!='f') error; p2 = file; while (*p2++ = *p1++); return; } if (c!=' ') error; while ((c = getchar()) == ' ');  if (c=='\n') error; p1 = file; do { *p1++ = c; if (c==' ' || c==EOF) error; } while ((c = getchar()) != '\n'); *p1++ = 0; if (savedfile[0]==0 || comm=='e' || comm=='f') { p1 = savedfile; p2 = file; while (*p1++ = *p2++); } } exfile() { close(io); io = -1; if (vflag) { putd(); putchar('\n'); } } onintr() { signal(SIGINTR, onintr); putchar('\n'); lastc = '\n'; error; } errfunc() { register c; listf = 0; puts("?"); count[0] = 0; seek(0, 0, 2); pflag = 0; if (globp)  lastc = '\n'; globp = 0; peekc = lastc; while ((c = getchar()) != '\n' && c != EOF); if (io > 0) { close(io); io = -1; } reset(); } getchar() { if (lastc=peekc) { peekc = 0; return(lastc); } if (globp) { if ((lastc = *globp++) != 0) return(lastc); globp = 0; return(EOF); } if (read(0, &lastc, 1) <= 0) return(lastc = EOF); lastc =& 0177; return(lastc); } gettty() { register c, gf; register char *p; p = linebuf; gf = globp; while ((c = getchar()) != '\n') { if (c==EOF) { if (gf) peekc = c; return(c); } if ((c =& 0177) == 0) continue; *p++ = c; if (p >= &linebuf[LBSIZE-2]) error; } *p++ = 0; if (linebuf[0]=='.' && linebuf[1]==0) return(EOF); return(0); } getfile() { register c; register char *lp, *fp; lp = linebuf; fp = nextip; do { if (--ninbuf < 0) { if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0) return(EOF); fp = genbuf; } if (lp >= &linebuf[LBSIZE]) error; if ((*lp++ = c = *fp++ & 0177) == 0) { lp--; continue; } if (++count[1] == 0) ++count[0]; } while (c != '\n'); *--lp = 0; nextip = fp; return(0); } putfile() { int *a1, n; register char *fp, *lp; register nib; nib = 512; fp = genbuf; a1 = addr1; do { lp = getline(*a1++); for (;;) { if (--nib < 0) { n = fp-genbuf; if(write(io, genbuf, n) != n) { puts(WRERR); error; } nib = 511; fp = genbuf; } if (++count[1] == 0) ++count[0]; if ((*fp++ = *lp++) == 0) { fp[-1] = '\n'; break;  } } } while (a1 <= addr2); n = fp-genbuf; if(write(io, genbuf, n) != n) { puts(WRERR); error; } } append(f, a) int (*f)(); { register *a1, *a2, *rdot; int nline, tl; struct { int integer; }; nline = 0; dot = a; while ((*f)() == 0) { if (dol >= endcore) { if (sbrk(1024) == -1) { lastc = '\n'; puts("MEM"); error; } endcore.integer =+ 1024; } tl = putline(); nline++; a1 = ++dol; a2 = a1+1; rdot = ++dot; while (a1 > rdot) *--a2 = *--a1; *rdot = tl; } return(nline); } unix() { register savint, pid, rpid; int retcode; setnoaddr(); if ((pid = fork()) == 0) { signal(SIGHUP, onhup); signal(SIGQUIT, onquit); execl("/bin/sh", "sh", "-t", 0); exit(0100); } savint = signal(SIGINTR, 1); while ((rpid = wait(&retcode)) != pid && rpid != -1); signal(SIGINTR, savint); puts("!"); } quit() { if (vflag && fchange) { fchange = 0; error; } unlink(tfname); exit(0); } delete() { register *a1, *a2, *a3; setdot(); newline(); nonzero(); a1 = addr1; a2 = addr2+1; a3 = dol; dol =- a2 - a1; do *a1++ = *a2++; while (a2 <= a3); a1 = addr1; if (a1 > dol) a1 = dol; dot = a1; fchange = 1; } gdelete() { register *a1, *a2, *a3; a3 = dol; for (a1=zero+1; (*a1&01)==0; a1++) if (a1>=a3) return; for (a2=a1+1; a2<=a3;) { if (*a2&01) { a2++; dot = a1; } else *a1++ = *a2++; } dol = a1-1; if (dot>dol) dot = dol; fchange = 1; } getline(tl) { register char *bp, *lp; register nl; lp = linebuf; bp = getblock(tl, READ); nl = nleft; tl =& ~0377; while (*lp++ = *bp++) if (--nl == 0) { bp = getblock(tl=+0400, READ); nl = nleft; } return(linebuf); } putline() { register char *bp, *lp; register nl; int tl; fchange = 1; lp = linebuf; tl = tline; bp = getblock(tl, WRITE); nl = nleft; tl =& ~0377; while (*bp = *lp++) { if (*bp++ == '\n') { *--bp = 0; linebp = lp; break; } if (--nl == 0) { bp = getblock(tl=+0400, WRITE); nl = nleft; } } nl = tline; tline =+ (((lp-linebuf)+03)>>1)&077776; return(nl); } getblock(atl, iof) { extern read(), write(); register bno, off; bno = (atl>>8)&0377; off = (atl<<1)&0774; if (bno >= 255) { lastc = '\n'; puts(TMPERR); error; } nleft = 512 - off; if (bno==iblock) { ichanged =| iof; return(ibuff+off); } if (bno==oblock) return(obuff+off); if (iof==READ) { if (ichanged) blkio(iblock, ibuff, write); ichanged = 0; iblock = bno; blkio(bno, ibuff, read); return(ibuff+off); } if (oblock>=0) blkio(oblock, obuff, write); oblock = bno; return(obuff+off); } blkio(b, buf, iofcn) int (*iofcn)(); { seek(tfile, b, 3); if ((*iofcn)(tfile, buf, 512) != 512) { puts(TMPERR); error; } } init() { register *markp; close(tfile); tline = 2; for (markp = names; markp < &names[26]; ) *markp++ = 0; subnewa = 0; anymarks = 0; iblock = -1; oblock = -1; ichanged = 0; close(creat(tfname, 0600)); tfile = open(tfname, 2); brk(fendcore); dot = zero = dol = fendcore; endcore = fendcore - 2; } global(k) { register char *gp; register c; register int *a1; char globuf[GBSIZE]; if (globp) error; setall(); nonzero(); if ((c=getchar())=='\n') error; compile(c); gp = globuf; while ((c = getchar()) != '\n') { if (c==EOF) error; if (c=='\\') { c = getchar(); if (c!='\n') *gp++ = '\\'; } *gp++ = c; if (gp >= &globuf[GBSIZE-2]) error; } *gp++ = '\n'; *gp++ = 0; for (a1=zero; a1<=dol; a1++) { *a1 =& ~01; if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k) *a1 =| 01; } /* * Special case: g/.../d (avoid n^2 algorithm) */ if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') { gdelete(); return; } for (a1=zero; a1<=dol; a1++) { if (*a1 & 01) { *a1 =& ~01; dot = a1; globp = globuf; commands(); a1 = zero; } } } substitute(inglob) { register gsubf, *a1, nl; int *markp; int getsub(); gsubf = compsub(); for (a1 = addr1; a1 <= addr2; a1++) { if (execute(0, a1)==0) continue; inglob =| 01; dosub(); if (gsubf) { while (*loc2) { if (execute(1, 0)==0) break; dosub(); } } subnewa = putline(); *a1 =& ~01; if (anymarks) { for (markp = names; markp < &names[26]; markp++) if (*markp == *a1) *markp = subnewa; } subolda = *a1; *a1 = subnewa; nl = append(getsub, a1); a1 =+ nl; addr2 =+ nl; } if (inglob==0) error; } compsub() { register seof, c; register char *p; if ((seof = getchar()) == '\n' || seof == ' ') error; compile(seof); p = rhsbuf; for (;;) { c = getchar(); if (c=='\\')  c = getchar() | 0200; if (c=='\n') error; if (c==seof) break; *p++ = c; if (p >= &rhsbuf[LBSIZE/2]) error; } *p++ = 0; if ((peekc = getchar()) == 'g') { peekc = 0; newline(); return(1); } newline(); return(0); } getsub() { register char *p1, *p2; p1 = linebuf; if ((p2 = linebp) == 0) return(EOF); while (*p1++ = *p2++); linebp = 0; return(0); } dosub() { register char *lp, *sp, *rp; int c; lp = linebuf; sp = genbuf; rp = rhsbuf; while (lp < loc1) *sp++ = *lp++; while (c = *rp++) { if (c=='&') { sp = place(sp, loc1, loc2); continue; } else if (c<0 && (c =& 0177) >='1' && c < nbra+'1') { sp = place(sp, braslist[c-'1'], braelist[c-'1']); continue; } *sp++ = c&0177; if (sp >= &genbuf[LBSIZE]) error; } lp = loc2; loc2 = sp - genbuf + linebuf; while (*sp++ = *lp++) if (sp >= &genbuf[LBSIZE]) error; lp = linebuf; sp = genbuf; while (*lp++ = *sp++); } place(asp, al1, al2) { register char *sp, *l1, *l2; sp = asp; l1 = al1; l2 = al2; while (l1 < l2) { *sp++ = *l1++; if (sp >= &genbuf[LBSIZE]) error; } return(sp); } move(cflag) { register int *adt, *ad1, *ad2; int getcopy(); setdot(); nonzero(); if ((adt = address())==0) error; newline(); if (cflag) { ad1 = dol; append(getcopy, ad1++); ad2 = dol; } else { ad2 = addr2; for (ad1 = addr1; ad1 <= ad2;) *ad1++ =& ~01; ad1 = addr1; } ad2++; if (adt= ad2) { dot = adt++; reverse(ad1, ad2); reverse(ad2, adt); reverse(ad1, adt); } else error; fchange = 1; } reverse(aa1, aa2) { register int *a1, *a2, t; a1 = aa1; a2 = aa2; for (;;) { t = *--a2; if (a2 <= a1) return; *a2 = *a1; *a1++ = t; } } getcopy() { if (addr1 > addr2) return(EOF); getline(*addr1++); return(0); } compile(aeof) { register eof, c; register char *ep; char *lastep; char bracket[NBRA], *bracketp; int cclcnt; ep = expbuf; eof = aeof; bracketp = bracket; if ((c = getchar()) == eof) { if (*ep==0) error; return; } circfl = 0; nbra = 0; if (c=='^') { c = getchar(); circfl++; } peekc = c; lastep = 0; for (;;) { if (ep >= &expbuf[ESIZE]) goto cerror; c = getchar(); if (c==eof) { if (bracketp != bracket) goto cerror; *ep++ = CEOF; return; } if (c!='*') lastep = ep; switch (c) { case '\\': if ((c = getchar())=='(') { if (nbra >= NBRA) goto cerror;  *bracketp++ = nbra; *ep++ = CBRA; *ep++ = nbra++; continue; } if (c == ')') { if (bracketp <= bracket) goto cerror; *ep++ = CKET; *ep++ = *--bracketp; continue; } if (c>='1' && c<'1'+NBRA) { *ep++ = CBACK; *ep++ = c-'1'; continue; } *ep++ = CCHR; if (c=='\n') goto cerror; *ep++ = c; continue; case '.': *ep++ = CDOT; continue; case '\n': goto cerror; case '*': if (lastep==0 || *lastep==CBRA || *lastep==CKET)  goto defchar; *lastep =| STAR; continue; case '$': if ((peekc=getchar()) != eof) goto defchar; *ep++ = CDOL; continue; case '[': *ep++ = CCL; *ep++ = 0; cclcnt = 1; if ((c=getchar()) == '^') { c = getchar(); ep[-2] = NCCL; } do { if (c=='\n') goto cerror; if (c=='-' && ep[-1]!=0) { if ((c=getchar())==']') { *ep++ = '-'; cclcnt++; break; } while (ep[-1]=&expbuf[ESIZE]) goto cerror; } } *ep++ = c; cclcnt++; if (ep >= &expbuf[ESIZE]) goto cerror; } while ((c = getchar()) != ']'); lastep[1] = cclcnt; continue; defchar: default: *ep++ = CCHR; *ep++ = c; } } cerror: expbuf[0] = 0; nbra = 0; error; } execute(gf, addr) int *addr; { register char *p1, *p2, c; for (c=0; c= curlp) { if (advance(lp, ep)) return(1); lp =- braelist[i] - braslist[i]; } continue; case CDOT|STAR: curlp = lp; while (*lp++); goto star; case CCHR|STAR: curlp = lp; while (*lp++ == *ep); ep++; goto star; case CCL|STAR: case NCCL|STAR: curlp = lp; while (cclass(ep, *lp++, ep[-1]==(CCL|STAR))); ep =+ *ep; goto star; star: do { lp--; if (lp==locs) break; if (advance(lp, ep)) return(1); } while (lp > curlp); return(0); default: error; } } backref(i, lp) register i; register char *lp; { register char *bp; bp = braslist[i]; while (*bp++ == *lp++) if (bp >= braelist[i]) return(1); return(0); } cclass(aset, ac, af) { register char *set, c; register n; set = aset; if ((c = ac) == 0) return(0); n = *set++; while (--n) if (*set++ == c) return(af); return(!af); } putd() { register r; extern ldivr; count[1] = ldiv(count[0], count[1], 10); count[0] = 0; r = ldivr; if (count[1]) putd(); putchar(r + '0'); } puts(as) { register char *sp; sp = as; col = 0; while (*sp) putchar(*sp++); putchar('\n'); } char line[70]; char *linp line; putchar(ac) { register char *lp; register c; lp = linp; c = ac; if (listf) { col++; if (col >= 72) { col = 0; *lp++ = '\\'; *lp++ = '\n'; } if (c=='\t') { c = '>'; goto esc; } if (c=='\b') { c = '<'; esc: *lp++ = '-'; *lp++ = '\b'; *lp++ = c; goto out; } if (c<' ' && c!= '\n') { *lp++ = '\\'; *lp++ = (c>>3)+'0'; *lp++ = (c&07)+'0'; col =+ 2; goto out; } } *lp++ = c; out: if(c == '\n' || lp >= &line[64]) { linp = line; write(1, line, lp-line); return; } linp = lp; } ter c; lp = linp; c = ac; if (listf) { col++; if (col >= 72) { col = 0; *lp++ = '\\'; *lp++ = '\n'; } if (c=='\t') { c = '>'; goto esc; } if (c=='\b') { c = '<'; esc: *lp++ = '-'; *lp++ = '\b'; *lp++ = c; goto out; } if (c<' ' && c!= '\n') { *lp++ = '\\'; *lp++ = (c>>3)+'0'; *lp++ = (c&07)+'0'; col =+ 2; goto out; } } *lp++ = c; out: if(c == '\n' || lp >= &line[64]) { linp = line; write(1, /* exit -- end runcom */ main(argc, argv) char **argv; { seek(0, 0, 2); exit(--argc<=0? 0: atob(argv[1])); } atob(ptr) char *ptr; { register char *p; register n, base; static char base0; n = 0; p = ptr; base = 10; if(*p == '-') p++; if(*p == '0') { base = 8; p++; } base0 = base + '0'; while(*p >= '0' && base0 > *p) { n =* base; n =+ *p++; n =- '0'; } if(*ptr == '-') n = -n; return(n); } } } *lp++ = c; out: if(c == '\n' || lp >= &line[64]) { linp = line; write(1, .globl sqrt ldfps = 170100^tst / ldfps $240 / begin: mov $1,r0 sys write; 1f; 2f-1f .data 1: 2: .even .text / jsr r5,atof; getch / tstf fr0 cfcc bpl 9f; jmp ouch; 9: bne 9f; jmp ouch; 9: cmpf big,fr0 cfcc bgt 9f; jmp ouch; 9: / movf fr0,n jsr r5,sqrt movf fr0,v movf n,fr0 jsr r5,ftoa; wrchar mov $1,r0 sys write; nl; 1 / movf $one,fr0 movf fr0,fr4 / movf n,fr0 movf $two,fr1 jsr r5,xt / movf n,fr0 movif $3,fr1 jsr r5,xt / movf n,fr0 movif $5,fr1 jsr r5,xt / movf n,fr0 movif $7,fr1 jsr r5,xt / movf n,fr0 movif $11.,fr1 mov $tab+2,r4 jsr r5,xx jmp begin / xt: movf fr0,fr2 divf fr1,fr2 modf $one,fr2 movf fr3,fr2 mulf fr1,fr2 cmpf fr2,fr0 cfcc beq hit2 rts r5 / / xx: movf fr0,fr2 divf fr1,fr2 modf fr4,fr2 cfcc bne 9f; mov $xx,-(sp); jmp hit; 9: / mov (r4)+,kazoo kazoo =.+2 addf $kazoo,fr1 cmp r4,$tabend blo 1f mov $tab,r4 1: / cmpf v,fr1 cfcc bge xx cmpf $one,fr0 cfcc beq 1f mov $1,r0 sys write; sp5; 5 movf n,fr0 jsr r5,ftoa; wrchar mov $1,r0 sys write; nl; 1 1: rts r5 / / / hit2: movf fr1,t movf fr3,n movf fr3,fr0 jsr r5,sqrt movf fr0,v mov $1,r0 sys write; sp5; 5 movf t,fr0 jsr r5,ftoa; wrchar mov $1,r0 sys write; nl; 1 movf n,fr0 movf t,fr1 jmp xt / hit: movf fr1,t movf fr3,n movf fr3,fr0 jsr r5,sqrt movf fr0,v mov $1,r0 sys write; sp5; 5 movf t,fr0 jsr r5,ftoa; wrchar mov $1,r0 sys write; nl; 1 movf n,fr0 movf t,fr1 rts pc / / / get one character from the console. / called from atof. / getch: clr r0 sys read; ch; 1 bec 9f; sys exit; 9: tst r0; bne 9f; sys exit; 9: mov ch,r0 rts r5 / / / write one character on the console / called from ftoa. / wrchar: mov r0,ch mov $1,r0 sys write; ch; 1 rts r5 / / / read and convert a line from the console into fr0. / atof: mov r1,-(sp) movif $10.,r3 clrf r0 1: jsr r5,*(r5) sub $'0,r0 cmp r0,$9. bhi 2f mulf r3,r0 movif r0,r1 addf r1,r0 br 1b 2: cmp r0,$' -'0 beq 1b / mov (sp)+,r1 tst (r5)+ rts r5 / / / / ftoa: mov $ebuf,r2 1: modf tenth,fr0 movf fr0,fr2 movf fr1,fr0 addf $epsilon,fr2 modf $ten,fr2 movfi fr3,r0 movb r0,-(r2) tstf fr0 cfcc bne 1b 1: movb (r2)+,r0 add $60,r0 jsr r5,*(r5) cmp r2,$ebuf blo 1b tst (r5)+ rts r5 / epsilon = 037114 tenth: 037314; 146314; 146314; 146315 .bss buf: .=.+18. ebuf: .text / / / / complain about a number which the program / is unable to digest ouch: mov $1,r0 sys write; 1f; 2f-1f jmp begin / 1: 2: .even / / one = 40200 two = 40400 four = 40600 ten = 41040 / .data big: 056177; 177777; 177777; 177777 nl: <\n> sp5: < > .even / tab: 41040; 40400; 40600; 40400; 40600; 40700; 40400; 40700 40600; 40400; 40600; 40700; 40700; 40400; 40700; 40600 40400; 40700; 40600; 40700; 41000; 40600; 40400; 40600 40400; 40600; 41000; 40700; 40600; 40700; 40400; 40600 40700; 40400; 40700; 40700; 40600; 40400; 40600; 40700 40400; 40700; 40600; 40400; 40600; 40400; 41040; 40400 tabend: / .bss ch: .=.+2 t: .=.+8 n: .=.+8 v: .=.+8 .text o = 40400 four = 40600 ten = 41040 / .data big: 056177; 177777/* Fortran command */ char *tmp; char ts[1000]; char *tsp ts; char *av[50]; char *clist[50]; char *llist[50]; int instring; int pflag; int cflag; int *ibuf; int *ibuf1; int *ibuf2; int *obuf; char *lp; char *line; int lineno; int exfail; struct symtab { char name[8]; char *value; } *symtab; int symsiz 200; struct symtab *defloc; struct symtab *incloc; char *stringbuf; main(argc, argv) char *argv[]; { char *t; int nc, nl, i, j, c, nxo; int dexit(); i = nc = nl = nxo = 0; while(++i < argc) { if(*argv[i] == '-') switch (argv[i][1]) { default: goto passa; case 'p': pflag++; case 'c': cflag++; break; } else { passa: t = argv[i]; if(getsuf(t)=='f') { clist[nc++] = t; t = setsuf(copy(t), 'o'); } if (nodup(llist, t)) { llist[nl++] = t; if (getsuf(t)=='o') nxo++; } } } if(nc==0) goto nocom; signal(2, &dexit); for (i=0; i1) printf("%s:\n", clist[i]); tmp = 0; av[0] = "fc1"; av[1] = expand(clist[i]); if (pflag || exfail) continue; if (av[1] == 0) { cflag++; continue; } av[2] = 0; t = callsys("/usr/fort/fc1", av); if(tmp) cunlink(tmp); if(t) { cflag++; continue; } av[0] = "as"; av[1] = "-"; av[2] = "f.tmp1"; av[3] = 0; callsys("/bin/as", av); t = setsuf(clist[i], 'o'); cunlink(t); if(link("a.out", t) || cunlink("a.out")) { printf("move failed: %s\n", t); cflag++; } } nocom: if (cflag==0 && nl!=0) { i = 0; av[0] = "ld"; av[1] = "-x"; av[2] = "/lib/fr0.o"; j = 3; while(ivalue = defloc->name; incloc = lookup("include", 1); incloc->value = incloc->name; stringbuf = sbf; line = ln; lineno = 0; tmp = setsuf(copy(file), 'i'); if (fcreat(tmp, obuf) < 0) { printf("Can't creat %s\n", tmp); dexit(); } while(getline()) { if (ibuf==ibuf2) putc(001, obuf); /*SOH: insert */ if (ln[0] != '#') for (lp=line; *lp!='\0'; lp++) putc(*lp, obuf); putc('\n', obuf); } fflush(obuf); close(obuf[0]); close(ibuf1[0]); return(tmp); } getline() { int c, sc, state; struct symtab *np; char *namep, *filname; if (ibuf==ibuf1) lineno++; lp = line; *lp = '\0'; state = 0; if ((c=getch()) == '#') state = 1; while (c!='\n' && c!='\0') { if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_') { namep = lp; sch(c); while ('a'<=(c=getch()) && c<='z' ||'A'<=c && c<='Z' ||'0'<=c && c<='9' ||c=='_') sch(c); sch('\0'); lp--; np = lookup(namep, state); if (state==1) { if (np==defloc) state = 2; else if (np==incloc) state = 3; else { error("Undefined control"); while (c!='\n' && c!='\0') c = getch(); return(c); } } else if (state==2) { np->value = stringbuf; while ((c=getch())!='\n' && c!='\0') savch(c); savch('\0'); return(1);  } continue; } else if ((sc=c)=='\'' || sc=='"') { sch(sc); filname = lp; instring++; while ((c=getch())!=sc && c!='\n' && c!='\0') { sch(c); if (c=='\\') sch(getch()); } instring = 0; if (state==3) { *lp = '\0'; while ((c=getch())!='\n' && c!='\0'); if (ibuf==ibuf2) error("Nested 'include'"); if (fopen(filname, ibuf2)<0) error("Missing file %s", filname); else ibuf = ibuf2; return(c); } } sch(c); c = getch(); } sch('\0'); if (state>1) error("Control syntax"); return(c); } error(s, x) { printf("%d: ", lineno); printf(s, x); putchar('\n'); exfail++; cflag++; } sch(c) { if (lp==line+194) error("Line overflow"); *lp++ = c; if (lp>line+195) lp = line+195; } savch(c) { *stringbuf++ = c; } getch() { static peekc; int c; if (peekc) { c = peekc; peekc = 0; return(c); } loop: if ((c=getc1())=='/' && !instring) { if ((peekc=getc1())!='*') return('/'); peekc = 0; for(;;) { c = getc1();  cloop: switch (c) { case '\0': return('\0'); case '*': if ((c=getc1())=='/') goto loop; goto cloop; case '\n': if (ibuf==ibuf1) { putc('\n', obuf); lineno++; } continue; } } } return(c); } getc1() { int c; if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) { close(ibuf2[0]); ibuf = ibuf1; putc('\n', obuf); c = getc1(); } if (c<0) return(0); return(c); } lookup(namep, enterf) char *namep; { char *np, *snp; struct symtab *sp; int i, c;  np = namep; i = 0; while (c = *np++) i =+ c; i =% symsiz; sp = &symtab[i]; while (sp->name[0]) { snp = sp; np = namep; while (*snp++ == *np) if (*np++ == '\0' || np==namep+8) { if (!enterf) subst(namep, sp); return(sp); } if (sp++ > &symtab[symsiz]) sp = symtab; } if (enterf) { for (i=0; i<8; i++) if (sp->name[i] = *namep) namep++; while (*namep) namep++; } return(sp); } subst(np, sp) char *np; struct symtab *sp; { char *vp; lp = np; if ((vp = sp->value) == 0) return; sch(' '); while (*vp) sch(*vp++); sch(' '); } getsuf(s) char s[]; { int c; char t, *os; c = 0; os = s; while(t = *s++) if (t=='/') c = 0; else c++; s =- 3; if (c<=14 && c>2 && *s++=='.') return(*s); return(0); } setsuf(s, ch) char s[]; { char *os; os = s; while(*s++); s[-2] = ch; return(os); } callsys(f, v) char f[], *v[]; { int t, status; if ((t=fork())==0) { signal(2, 0); execv(f, v); printf("Can't find %s\n", f); exit(1); } else if (t == -1) { printf("Try again\n"); return(1); } while(t!=wait(&status)); if ((t=(status&0377)) != 0 && t!=14) { if (t!=2) /* interrupt */ printf("Fatal error in %s\n", f); dexit(); } return((status>>8) & 0377); } copy(s) char s[]; { char *otsp; otsp = tsp; while(*tsp++ = *s++); return(otsp); } nodup(l, s) char **l, s[]; { char *t, *os, c; if (getsuf(s) != 'o') return(1); os = s; while(t = *l++) { s = os; while(c = *s++) if (c != *t++) break; if (*t++ == '\0')  return(0); } return(1); } cunlink(f) char *f; { if (f==0) return(0); return(unlink(f)); } 377)) != 0 && t!=14) { if (t!=2) /* interrupt */ printf("Fatal error in %s\n", f); dexit(); } return((status>>8) & 0377); } copy(s) char s[]; { char *otsp; otsp = tsp; while(*tsp++ = *s++); return(otsp); } nodup(l, s) char **l, s[]; { char *t, *os, c; if (getsuf(s) != 'o') return(1); os = s; while(t = *l++) { s = os; while(c = *s++) if (c != *t++) break; if (*t++ == '\0') int ibuf[260]; main(argc, argv) char **argv; { while(argc > 1) { printf("%s: ", argv[1]); type(argv[1]); argc--; argv++; } } type(file) char *file; { int mbuf[20]; if(stat(file, mbuf) < 0) { printf("cannot stat\n"); return; } switch(mbuf[2]&060000) { case 020000: printf("character"); goto spcl; case 040000: printf("directory\n"); return; case 060000: printf("block"); spcl: printf(" special (%d/%d)\n", (mbuf[6]>>8)&0377, mbuf[6]&0377); return; } ibuf[0] = open(file, 0); if(ibuf[0] < 0) { printf("cannot open\n"); return; } read(ibuf[0], mbuf, 2); switch(*mbuf) { case 0407: printf("old executable\n"); goto out; case 0410: printf("new executable\n"); goto out; case 0177555: printf("archive\n"); goto out; } ibuf[1] = 0; ibuf[2] = 0; ibuf[3] = 0; digram(); out: close(ibuf[0]); } digram() { printf("unknown\n"); } intf("block"); spcl: printf(" special (%d/%d)\n", (mbuf[6]>>8)&0377, mbuf[6]&0377); return; } ibuf[0] = o/* find -- find files in a pathname. Use of find is documented in /usr/man/man1/find.1 . In addition, find has a secret first arg "+" which causes each file name to be printed along with a period if the predicates succeed. */ int randlast; char *pathname; int verbose; struct anode { int (*F)(); struct anode *L, *R; } node[100]; int nn; /* number of nodes */ char *fname, *path; int now[2]; int ap, ac; char **av; struct ibuf { int idev; int inum; int iflags; char inl; char iuid; char igid; char isize0; int isize; int iaddr[8]; int iatime[2]; int imtime[2]; } statb; main(argc,argv) char *argv[]; { struct anode *exlist; struct anode *exp(); struct anode *e1(); struct anode *e2(); struct anode *e3(); struct anode *mk(); int find(); time(&now); ac = argc; av = argv; ap = 2; pathname = argv[1]; if(compstr(argv[1],"+")==0) { verbose++; ap++; pathname = argv[2]; } else verbose = 0; argv[argc] = 0; if(argc<3) { printf("Insufficient args\n"); exit(-1); } if(!(exlist = exp())) { /* parse and compile the arguments */ printf("Odd usage\n"); exit(-1); } if(ap=ac) return(""); return(av[ap++]); } find(exlist,fullname) /* execute predicat list with current file */ struct anode *exlist; char *fullname; { register int i; path = fullname; if(verbose) printf("%s",path); for(i=0;fullname[i];++i) if(fullname[i]=='/') fname = &fullname[i+1]; i = (*exlist->F)(exlist); if(verbose) if(i) printf(".\n"); else printf("\n"); } /* execution time functions */ and(p) struct anode *p; { return(((*p->L->F)(p->L)) && ((*p->R->F)(p->R))?1:0); } or(p) struct anode *p; { return(((*p->L->F)(p->L)) || ((*p->R->F)(p->R))?1:0); } not(p) struct anode *p; { return( !((*p->L->F)(p->L))); } glob(p) struct { int f; char *pat; } *p; { return(gmatch(fname,p->pat)); } print() { printf("%s\n",path); return(1); } mtime(p) struct { int f, t, s; } *p; { return(scomp((now[0]-statb.imtime[0])*3/4,p->t,p->s)); } atime(p) struct { int f, t, s; } *p; { return(scomp((now[0]-statb.iatime[0])*3/4,p->t,p->s)); } user(p) struct { int f, u, s; } *p; { return(scomp(statb.iuid,p->u,p->s)); } group(p) struct { int f, u; } *p; { return(p->u == statb.igid); } links(p) struct { int f, link, s; } *p; { return(scomp(statb.inl,p->link,p->s)); } size(p) struct { int f, sz, s; } *p; { register int i; i = statb.isize0 << 7; i=| (statb.isize >> 9) & 0777; return(scomp(i,p->sz,p->s)); } perm(p) struct { int f, per, s; } *p; { int i; i = (p->s=='-') ? p->per : 03777; /* '-' means only arg bits */ return((statb.iflags & i & 017777) == p->per); } type(p) struct { int f, per, s; } *p; { return((statb.iflags&060000)==p->per); } exeq(p) struct { int f, com; } *p; { return(doex(p->com)); } ok(p) struct { int f, com; } *p; { char c; int yes; yes = 0; printf("%s ... %s ...? ",av[p->com],path); if((c=getchar())=='y') yes = 1; while(c!='\n') c = getchar(); if(yes) return(doex(p->com)); return(0); } /* support functions */ scomp(a,b,s) char s; { /* funny signed compare */ if(s == '+') return(a > b); if(s == '-') return(a < (b * -1)); return(a == b); } doex(com) { int ccode; int np, i, c; char *nargv[50], *ncom, *na; ccode = np = 0; while (na=av[com++]) { if(compstr(na,";")==0) break; if(compstr(na,"{}")==0) nargv[np++] = path; else nargv[np++] = na; } nargv[np] = 0; if (np==0) return(-1); if(fork()) /*parent*/ wait(&ccode); else { /*child*/ execv(nargv[0], nargv, np); i = 0; ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; while(c=nargv[0][i]) { ncom[9+i++] = c; } ncom[9+i] = '\0'; execv(ncom+4, nargv, np); execv(ncom, nargv, np); exit(-1); } return(ccode ? 0:1); } char fin[518]; getunum(s) char *s; { /* find username in /etc/passwd & return num. */ int i; char str[20], *sp, c; extern double atof(); i = -1; fin[0] = open("/etc/passwd",0); while(c = getchar()) { if(c=='\n') { sp = str; while((*sp = getchar()) != ':') if(! *sp++) goto RET; *sp = '\0'; if(compstr(str,s)==0) { while((c=getchar()) != ':') if(! c) goto RET; sp = str; while((*sp = getchar()) != ':') sp++; *sp = '\0'; i = atof(str); break; } } } RET: close(fin); fin[0] = 0; return(i); } compstr(s1,s2) char s1[], s2[]; { /* compare strings: */ register char *c1, *c2; c1 = s1; c2 = s2; while(*c1 == *c2) if(*c1++ == '\0') return(0); /* s1 == s2 */ else c2++; return(*c1 > *c2 ? 1 : -1); } int descend(name,goal,func,arg) int (*func)(); char *name, goal; { int dir /* open directory */, offset /* in directory */; int dsize, top; struct { int dinode; char dname[14]; } dentry[32]; register int i, j, k; char aname[128]; if(stat(name,&statb)<0) { printf("--bad status %s\n",name); return(0); } /* if((statb.iflags&060000)!=040000){ /*not a directory*/ /* if(goal=='f'||goal=='b') /* search goal for files */ /* (*func)(arg,name); return(1); } else if(goal=='d' || goal=='b') /* search goal is directories */ /* (*func)(arg,name); */ (*func)(arg,name); if((statb.iflags&060000)!=040000) return(1); top = statb.isize; for(offset=0 ; offset < top ; offset =+ 512) { /* each block */ dsize = 512<(top-offset) ? 512 : (top-offset); if((dir=open(name,0))<0) { printf("--cannot open %s\n",name); return(0); } if(offset) seek(dir,offset,0); if(read(dir,&dentry,dsize)<0) { printf("--cannot read %s\n",name); return(0); } close(dir); for(i = 0; i < (dsize>>4); ++i) { /* each dir. entry */ if(dentry[i].dinode==0||dentry[i].dname[0]=='.') continue; if (dentry[i].dinode == -1) break; for(j=0;aname[j]=name[j];++j); if(aname[j-1]!='/') aname[j++] = '/'; for(k=0; (aname[j++]=dentry[i].dname[k]) && k<13; ++k); aname[j] = '\0'; if(descend(aname,goal,func,arg)==0) printf("--%s\n",name); } } return(1); } gmatch(s, p) /* string match as in glob */ char *s, *p; { if (*s=='.' && *p!='.') return(0); return(amatch(s, p)); } amatch(s, p) char *s, *p; { register int cc, scc, k; int c, lc; scc = *s; lc = 077777; switch (c = *p) { case '[': k = 0; while (cc = *++p) { switch (cc) { case ']': if (k) return(amatch(++s, ++p)); else return(0); case '-': k =| lc <= scc & scc <= (cc=p[1]); } if (scc==(lc=cc)) k++; } return(0); case '?': caseq: if(scc) return(amatch(++s, ++p)); return(0); case '*': return(umatch(s, ++p)); case 0: return(!scc); } if (c==scc) goto caseq; return(0); } umatch(s, p) char *s, *p; { if(*p==0) return(1); while(*s) if (amatch(s++,p)) return(1); return(0); } k = 0; while (cc = *++p) { switch (cc) { case ']': if (k) return(amatch(++s, ++p)); else return(0); case '-': k =| lc <= scc & scc <= (cc=p[1]); } if (scc==(lc=cc)) k++; } return(0); case '?': caseq: if(scc) return(amatch(++s, ++p)); return(0); case '*': return(umatch(s, ++p)); case 0: return(!scc); } if (c==scc) goto caseq; return(0); } umatch(s, p) char *s, *p; { if(*p==0) return(1); whil# /* * getty -- adapt to terminal speed on dialup, and call login * getty lnid [tname] */ /* * tty flags */ #define HUPCL 01 #define XTABS 02 #define LCASE 04 #define ECHO 010 #define CRMOD 020 #define RAW 040 #define ODDP 0100 #define EVENP 0200 #define ANYP 0300 /* * Delay algorithms */ #define CR1 010000 #define CR2 020000 #define CR3 030000 #define NL1 000400 #define NL2 001000 #define NL3 001400 #define TAB1 002000 #define TAB2 004000 #define TAB3 006000 #define FF1 040000 #define ERASE '#' #define KILL '@' /* * speeds */ #define B110 3 #define B150 5 #define B300 7 #define B1200 9 #define SIGINT 2 #define SIGQIT 3 #define CHNGD ('t'<<8)|01 /* change discipline ioctl command */ struct sgtty { char sgispd, sgospd; char sgerase, sgkill; int sgflag; } tmode; struct tab { int tname; /* this table name */ int nname; /* successor table name */ int iflags; /* initial flags */ int fflags; /* final flags */ int ispeed; /* input speed */ int ospeed; /* output speed */ char *message; /* login message */ } itab[] { /* table '0'-1-2 300,150,110 */ '0', 1, ANYP+RAW+NL1+CR1, ANYP+ECHO+XTABS+CR1, B300, B300, "\n\r\033;\007login: ", 1, 2, ANYP+RAW+NL1+CR1, EVENP+ECHO+FF1+CR2+TAB1+NL1, B150, B150, "\n\r\033:\006\006\017login: ", 2, '0', ANYP+RAW+NL1+CR1, ANYP+ECHO+CRMOD+XTABS+LCASE+CR1, B110, B110, "\n\rlogin: ", /* table '-' -- Console TTY 110 */ '-', '-', ANYP+RAW+NL1+CR1, ANYP+ECHO+CRMOD+XTABS+LCASE+CR1, B110, B110, "\n\rlogin: ", /* table '1' -- 150 */ '1', '1', ANYP+RAW+NL1+CR1, EVENP+ECHO+FF1+CR2+TAB1+NL1, B150, B150, "\n\r\033:\006\006\017login: ", /* table '2' -- 1200 */ '2', '2', ANYP+RAW+NL1+CR1, ANYP+XTABS+ECHO+CRMOD+FF1, B1200, B1200, "\n\r\033;login: ", /* table '4' -- 1200 */ '4', '4', RAW+NL1+CR1, EVENP+NL1, B1200, B1200, "\n\r;login: ", }; #define NITAB sizeof itab/sizeof itab[0] char name[16]; int crmod; int upper; int lower; int stin; int stout; char *line; char *CTTY "/dev/ln00"; main(argc, argv) char **argv; { register struct tab *tabp; register tname; register i; int discp; /* signal(SIGINT, 1); signal(SIGQIT, 0); */ stout = -1; if (argc == 1) { /* error */ puts(" lid [tname]\n"); sleep(20); exit(1); } line = "/dev/\0\0\0\0"; for(i=0;(line[i+5] = argv[1][i]); i++); chown(line,0); chmod(line,0622); discp = 0; switch(argc){ case 2: /*getty default*/ tname = '0'; break; case 4: /* line discipline argument */ discp = (*argv[3] - '0')<<8; default: /*tname argument*/ tname = *argv[2]; } switch(stin = open(line, -1)) { case -1: break; default: if (ioctl(stin, CHNGD, &discp) >= 0) { close(stin); break; } close(stin); puts(": illegal discipline change "); puts(line); puts("\n"); sleep(20); exit(1); } switch(stin=open(line,2)){ case -1: puts(": could not open "); puts(line); puts("\n"); sleep(20); exit(1); default: /*input file already there*/ close(stin); case 0: /*no file descriptors before this*/ stout = dup(0); if(stout != 1) close(stout); /*is output file opened?*/ break; /*output file created*/ } for (;;) { for(tabp = itab; tabp < &itab[NITAB]; tabp++) if(tabp->tname == tname) break; if(tabp >= &itab[NITAB]) tabp = itab; tmode.sgispd = tabp->ispeed; tmode.sgospd = tabp->ospeed; tmode.sgflag = tabp->iflags; tmode.sgispd = tabp->ispeed; tmode.sgospd = tabp->ospeed; stty(0, &tmode); puts(tabp->message); stty(0, &tmode); if(getname()) { tmode.sgerase = ERASE; tmode.sgkill = KILL; tmode.sgflag = tabp->fflags; if(crmod) tmode.sgflag =| CRMOD; if(upper) tmode.sgflag =| LCASE; if(lower) tmode.sgflag =& ~LCASE; stty(0, &tmode); execl("/bin/login", "login", name, 0); exit(1); } tname = tabp->nname; } } getname() { register char *np; register c; static cs; crmod = 0; upper = 0; lower = 0; np = name; do { if (read(0, &cs, 1) <= 0) exit(0); if ((c = cs&0177) == 0) return(0); write(1, &cs, 1); if (c>='a' && c <='z') lower++; else if (c>='A' && c<='Z') { upper++; c =+ 'a'-'A'; } else if (c==ERASE) { if (np > name) np--; continue; } else if (c==KILL) { np = name; continue; } *np++ = c; } while (c!='\n' && c!='\r' && np <= &name[16]); *--np = 0; if (c == '\r') { write(1, "\n", 1); crmod++; } else write(1, "\r", 1); return(1); } puts(as) char *as; { register i; if(stout == -1){ /*error condition case only*/ stout = open(CTTY,1); write(stout,"GETTY",5); } for(i=0;as[i];i++); write(stout,as,i); } '# /* global command -- glob params "*" in params matches r.e ".*" "?" in params matches r.e. "." "[...]" in params matches character class "[...a-z...]" in params matches a through z. perform command with argument list constructed as follows: if param does not contain "*", "[", or "?", use it as is if it does, find all files in current directory which match the param, sort them, and use them prepend the command name with "/bin" or "/usr/bin" as required. */ #define E2BIG 7 #define ENOEXEC 8 #define ENOENT 2 #define STRSIZ 5300 char ab[STRSIZ]; /* generated characters */ char *ava[500]; /* generated arguments */ char **av &ava[1]; char *string ab; int errno; int ncoll; main(argc, argv) char *argv[]; { register char *cp; register acctflg; if (argc < 3) { write(2, "Arg count\n", 10); return; } argv++; *av++ = *argv; while (--argc >= 2) expand(*++argv); if (ncoll==0) { write(2, "No match\n", 9); return; } acctflg = shexec(ava[1], &ava[1]); cp = cat("/usr/bin/", ava[1]); acctflg =+ shexec(cp+4, &ava[1]); acctflg =+ shexec(cp, &ava[1]); err(acctflg? ":permission denied!": ":not found"); write(2, "Command not found.\n", 19); } expand(as) char *as; { register char *s, *cs; register int dirf; char **oav; static struct { int ino; char name[16]; } entry; s = cs = as; while (*cs!='*' && *cs!='?' && *cs!='[') { if (*cs++ == 0) { *av++ = cat(s, ""); return; } } for (;;) { if (cs==s) { dirf = open(".", 0); s = ""; break; } if (*--cs == '/') { *cs = 0; dirf = open(s==cs? "/": s, 0); *cs++ = 0200; break; } } if (dirf<0) { write(2, "No directory\n", 13); exit(8); } oav = av; while (read(dirf, &entry, 16) == 16) { if (entry.ino==0) continue; if (match(entry.name, cs)) { *av++ = cat(s, entry.name); ncoll++; } } close(dirf); sort(oav); } sort(oav) char **oav; { register char **p1, **p2, **c; p1 = oav; while (p1 < av-1) { p2 = p1; while(++p2 < av) { if (compar(*p1, *p2) > 0) { c = *p1; *p1 = *p2; *p2 = c; } } p1++; } } err(s) { prs(s); prs("\n"); exit(8); } toolong() { err("Arg list too long"); } match(s, p) char *s, *p; { if (*s=='.' && *p!='.') return(0); return(amatch(s, p)); } amatch(as, ap) char *as, *ap; { register char *s, *p; register scc; int c, cc, ok, lc; s = as; p = ap; if (scc = *s++) if ((scc =& 0177) == 0) scc = 0200; switch (c = *p++) { case '[': ok = 0; lc = 077777; while (cc = *p++) { if (cc==']') { if (ok) return(amatch(s, p)); else return(0); } else if (cc=='-') { if (lc<=scc && scc<=(c = *p++)) ok++; } else if (scc == (lc=cc)) ok++; } return(0); default: if (c!=scc) return(0); case '?': if (scc) return(amatch(s, p)); return(0); case '*': return(umatch(--s, p)); case '\0': return(!scc); } } umatch(s, p) char *s, *p; { if(*p==0) return(1); while(*s) if (amatch(s++,p)) return(1); return(0); } compar(as1, as2) char *as1, *as2; { register char *s1, *s2; s1 = as1; s2 = as2; while (*s1++ == *s2) if (*s2++ == 0) return(0); return (*--s1 - *s2); } cat(as1, as2) char *as1, *as2; { register char *s1, *s2; register int c; s2 = string; s1 = as1; while (c = *s1++) { if (s2 > &ab[STRSIZ]) toolong(); c =& 0177; if (c==0) { *s2++ = '/'; break; } *s2++ = c; } s1 = as2; do { if (s2 > &ab[STRSIZ]) toolong(); *s2++ = c = *s1++; } while (c); s1 = string; string = s2; return(s1); } #define ENOENT 2 #define E2BIG 7 #define ENOEXEC 8 #define ENOMEM 12 #define EACCESS 13 #define ENOTDIR 20 #define EDIRECT 13 #define SHELL "/bin/sh" int ldivr; char nbuf[6]; shexec(afile, aargp) char *afile, *aargp[]; { register char *file, **rargp; extern errno; file = afile; rargp = aargp; execv(file, rargp); /* temp */ if(!errno || errno & 0177700) errno = EDIRECT; if(errno == ENOEXEC) { *rargp = file; *--rargp = SHELL+5; execv(SHELL, rargp); if(errno == ENOENT || errno == ENOTDIR) err("No Shell!"); } switch (errno) { case E2BIG: prs(*rargp); err(": arg list too long"); case ENOMEM: prs(*rargp); err(": not enough core"); default: prs(*rargp); prs(": unknown error (errno="); prn(errno); err(")."); case EACCESS: return(1); case ENOENT: case ENOTDIR: return(0); } } prs(as) char *as; { register char *s; s = as; while(*s) write(2, s++, 1); } prn(n) { prs(btoa(n, nbuf+5)); } btoa(n, ptr) char *ptr; { register char *p; register v; p = ptr; *p = 0;  v = n; do { v = ldiv(0, v, 10); *--p = ldivr | '0'; } while(v); return(p); } ng"); case ENOMEM: prs(*rargp); err(": not enough core"); default: prs(*rargp); prs(": unknown error (errno="); prn(errno); err(")."); case EACCESS: return(1); case ENOENT: case ENOTDIR: return(0); } } prs(as) char *as; { register char *s; s = as; while(*s) write(2, s++, 1); } prn(n) { prs(btoa(n, nbuf+5)); } btoa(n, ptr) char *ptr; { register char *p; register v; p = ptr; *p = 0; int offset 0; main(argc, argv) char *argv[]; { extern fin; char line[64]; int ln; struct{ char lobyte; char hibyte; }; ln = lnxx(0); if(argc<2 || (ln.lobyte != 'x' || ln.hibyte != 'x')){ write(2, "goto error\n", 11); seek(0, 0, 2); exit(12); } seek(0, 0, 0); fin = 0; loop: if (getlin(line)) { write(2, "label not found\n", 16); exit(1); } if (compar(line, argv[1])) goto loop; } getlin(s) char s[]; { register char ch; char getc(); l: if ((ch=getc())=='\0') return(1); if (ch!=':') { while(ch!='\n' && ch!='\0') ch = getc(); goto l; } do ch=getc(); while(ch==' ' || ch=='\t'); while (ch!=' ' && ch!='\t' && ch!='\n' && ch!='\0') { *s++ = ch; ch = getc(); } while(ch != '\n') ch = getc(); *s = '\0'; return(0); } compar(s1, s2) char s1[], s2[]; { do { if(*s1 != *s2++) return(1); } while(*s1++); return(0); } char getc() { char c; if(read(0, &c, 1) != 1) c=0; return(c); } ]; { register char ch; char getc(); l: if ((ch=getc())=='\0') return(1); if (ch!=':# /* * grep -- print lines matching (or not matching) a pattern * * status returns: * 0 - ok, and some matches * 1 - ok, but no matches * 2 - some error */ #define CBRA 1 #define CCHR 2 #define CDOT 4 #define CCL 6 #define NCCL 8 #define CDOL 10 #define CEOF 11 #define CKET 12 #define CBACK 18 #define STAR 01 #define LBSIZE 512 #define ESIZE 256 #define NBRA 9 char ibuf[512]; char expbuf[ESIZE]; long lnum; char linebuf[LBSIZE+1]; int bflag; int nflag; int cflag; int vflag; int nfile; int circf; int blkno; long tln; int nsucc; char *braslist[NBRA]; char *braelist[NBRA]; char bittab[] { 1, 2, 4, 8, 16, 32, 64, 128 }; int fmon; /* monitor file */ char *smon; /* monitor pointer */ char nl '\n'; /* monitor */; main(argc, argv) char **argv; { extern fout; fout = dup(1); flush(); while (--argc > 0 && (++argv)[0][0]=='-') switch (argv[0][1]) { case 'v': vflag++; continue; case 'b': bflag++; continue; case 'c': cflag++; continue; case 'n': nflag++; continue; default: printf2("Unknown flag\n"); continue; } if (argc<=0) exit(2); /* temporary monitoring */ /* if ((fmon = open("/usr/bwk/grep.pats", 2)) >= 0) { seek(fmon, 0, 2); for (smon = *argv; *smon; smon++) write(fmon, smon, 1); write(fmon, &nl, 1); close(fmon); } */ /* end of monitor */ compile(*argv); nfile = --argc; if (argc<=0) execute(0); else while (--argc >= 0) { argv++; execute(*argv); } flush(); exit(nsucc == 0); } compile(astr) char *astr; { register c; register char *ep, *sp; char *lastep; int cclcnt; char bracket[NBRA], *bracketp; int closed; char numbra; ep = expbuf; sp = astr; lastep = 0; bracketp = bracket; closed = numbra = 0; if (*sp == '^') { circf++; sp++; } for (;;) { if (ep >= &expbuf[ESIZE]) goto cerror; if ((c = *sp++) != '*') lastep = ep; switch (c) { case '\0': *ep++ = CEOF; return; case '.': *ep++ = CDOT; continue; case '*': if (lastep==0) goto defchar; *lastep =| STAR; continue; case '$': if (*sp != '\0') goto defchar; *ep++ = CDOL; continue; case '[': if(&ep[17] >= &expbuf[ESIZE]) goto cerror; *ep++ = CCL; if((c = *sp++) == '^') { for(cclcnt = 0; cclcnt < 16; cclcnt++) ep[cclcnt] = -1; ep[0] =& 0376; c = *sp++; } do { if(c == '\0') goto cerror; ep[c >> 3] =^ bittab[c & 07]; } while((c = *sp++) != ']'); ep =+ 16; continue; case '\\': if((c = *sp++) == '(') { if(numbra >= NBRA) {  goto cerror; } *bracketp++ = numbra; *ep++ = CBRA; *ep++ = numbra++; continue; } if(c == ')') { if(bracketp <= bracket) { goto cerror; } *ep++ = CKET; *ep++ = *--bracketp; closed++; continue; } if(c >= '1' && c <= '9') { if((c =- '1') >= closed) goto cerror; *ep++ = CBACK; *ep++ = c; continue; } defchar: default: *ep++ = CCHR; *ep++ = c; } } cerror: printf2("RE error\n"); } execute(file) { register char *p1, *p2; register c; int f; char *ebp, *cbp; if (file) { if ((f = open(file, 0)) < 0) { printf2("Can't open %s\n", file); } } else f = 0; ebp = ibuf; cbp = ibuf; lnum = 0; tln = 0; blkno = -1; for (;;) { lnum++; if((lnum&0377) == 0) flush(); p1 = linebuf; p2 = cbp; for (;;) { if (p2 >= ebp) { if ((c = read(f, ibuf, 512)) <= 0) { close(f); if (cflag) { if (nfile > 1) printf("%s:", file); printf("%ld\n", tln); } return; } blkno++; p2 = ibuf; ebp = ibuf+c; } if ((c = *p2++) == '\n') break; if(c) if (p1 < &linebuf[LBSIZE-1]) *p1++ = c; } *p1++ = 0; cbp = p2; p1 = linebuf; p2 = expbuf; if (circf) { if (advance(p1, p2)) goto found; goto nfound; } /* fast check for first character */ if (*p2==CCHR) { c = p2[1]; do { if (*p1!=c) continue; if (advance(p1, p2)) goto found; } while (*p1++); goto nfound; } /* regular algorithm */ do { if (advance(p1, p2)) goto found; } while (*p1++); nfound: if (vflag) succeed(file); continue; found: if (vflag==0) succeed(file); } } advance(alp, aep) { register char *lp, *ep, *curlp; char *nextep, c; char *bbeg; int ct; lp = alp; ep = aep; for (;;) switch (*ep++) { case CCHR: if (*ep++ == *lp++) continue; return(0); case CDOT: if (*lp++) continue; return(0); case CDOL: if (*lp==0) continue; return(0); case CEOF: return(1); case CCL: c = *lp++ & 0177; if(ep[c>>3] & bittab[c & 07]) { ep =+ 16; continue; } return(0); case CBRA: braslist[*ep++] = lp; continue; case CKET: braelist[*ep++] = lp; continue; case CBACK: bbeg = braslist[*ep]; ct = braelist[*ep++] - bbeg; if(ecmp(bbeg, lp, ct)) { lp =+ ct; continue; } return(0); case CBACK|STAR: bbeg = braslist[*ep]; ct = braelist[*ep++] - bbeg; curlp = lp; while(ecmp(bbeg, lp, ct)) lp =+ ct; while(lp >= curlp) { if(advance(lp, ep)) return(1);  lp =- ct; } return(0); case CDOT|STAR: curlp = lp; while (*lp++); goto star; case CCHR|STAR: curlp = lp; while (*lp++ == *ep); ep++; goto star; case CCL|STAR: curlp = lp; do { c = *lp++ & 0177; } while(ep[c>>3] & bittab[c & 07]); ep =+ 16; goto star; star: if(--lp == curlp) { continue; } if(*ep == CCHR) { c = ep[1]; do { if(*lp != c) continue; if(advance(lp, ep)) return(1); } while(lp-- > curlp); return(0); } do { if (advance(lp, ep)) return(1); } while (lp-- > curlp); return(0); default: printf2("RE botch\n"); } } cclass(aset, ac, af) { register char *set, c; register n; set = aset; if ((c = ac) == 0) return(0); n = *set++; while (--n) if (*set++ == c) return(af); return(!af); } printf2(s, a) { extern fout; flush(); fout = 2; printf(s, a); flush(); exit(2); } succeed(f) { nsucc = 1; if (cflag) { tln++; return; } if (nfile > 1) printf("%s:", f); if (bflag) printf("%u:", blkno); if (nflag) printf("%ld:", lnum); printf("%s\n", linebuf); } ecmp(a, b, count) char *a, *b; { while(count--) if(*a++ != *b++) return(0); return(1); } ter n; set = aset; if ((c = ac) == 0) return(0); n = *set++; while (--n) if (*set++ == c) return(af); return(!af); } printf2(s, a) { extern fout; flush(); fout = 2; printf(s, a); flush(); exit(2); } succeed(f) { nsucc = 1; if (cflag) { tln++; return; } if (nfile > 1) printf("%s:", f); if (bflag) printf("%u:", b# /* modified for 300S enter plot with ACK leave plot with ESC ACK BEL supposedly compatible with 300 */ #define ACK 006 /* ack */ #define BEL 007 /* exit plot mode */ #define ESC 033 /* escape */ #define HFWD '9' #define HREV '8' #define FREV '7' #define SO 016 /* shift out - enter greek */ #define SI 017 /* shift in */ #define UP 013 /* vt */ #define DN 012 #define RT ' ' #define LF '\b' #define enterplot putchar(006) /* putchar(ACK) */ #define leaveplot putchar(033); putchar(006) /* putchar(ESC); putchar(ACK) */ int restore(); int svmode, mode[3]; main(argc,argv) int argc; char **argv; { int c, textmode; extern int fin,fout; fin = dup(0); fout = dup(1); if ((signal(2, 1) & 01) == 0) signal(2, &restore); gtty(1, mode); svmode = mode[2]; mode[2] =& 0777757L; /* turn off cr-lf */ mode[2] =| 03; /* turn off delays, tabs */ stty(1, mode); textmode = 1; while( (c=getchar()) != '\0' ){ if( c==SO ){ special(); continue; } if (c== ACK) textmode = 1-textmode; if (c==BEL) textmode = 1; if( c=='\n' && textmode ) putchar(015); /* CR */ if( c!=ESC ){ putchar(c); continue; } enterplot; c = getchar(); if( c == HREV ) nplot(4,UP); else if( c == HFWD ) nplot(4,DN); else if( c == FREV ) nplot(8,UP); leaveplot; } flush(); restore(); } restore(){ mode[2] = svmode; stty(1, mode); exit(); } int alpha[] {LF,'c',RT,RT,'(',LF,0}; int beta[] {'B',LF,LF,DN,DN,'|',RT,RT,UP,UP,0}; int delta[] {'o',UP,UP,'<',DN,DN,0}; int DELTA[] {LF,LF,'/',-3,DN,'-',-4,RT,'-',-3,UP,'\\',LF,LF,0}; int epsilon[] {'<','-',0}; int eta[] {'n',RT,RT,DN,DN,'|',LF,LF,UP,UP,0}; int gamma[] {')',RT,'/',LF,0}; int GAMMA[] {LF,LF,'|',RT,RT,-3,UP,'-',-3,DN,RT,RT,'`',LF,LF,0}; int infinity[] {LF,LF,'c',-4,RT,'o',LF,LF,0}; int integral[] {'|','\'',RT,RT,'`',-3,LF,-6,DN,'\'',LF,'`',RT,RT,-6,UP,0}; int lambda[] {'\\',-4,DN,LF,'\'',DN,LF,'\'',-5,UP,RT,RT,0}; int LAMBDA[] {LF,LF,'/',-4,RT,'\\',LF,LF,0}; int mu[] {'u',LF,LF,',',RT,RT,0}; int nabla[] {LF,LF,'\\',-3,UP,'-',-4,RT,'-',-3,DN,'/',LF,LF,0}; int not[] {'-',-2,RT,UP,',',DN,-2,LF,0}; int nu[] {LF,'(',-3,RT,'/',LF,LF,0}; int omega[] {LF,'u',-3,RT,'u',LF,LF,0}; int OMEGA[] {'O',DN,DN,LF,'-',RT,RT,'-',LF,UP,UP,0}; int partial[] {'o',RT,DN,'`',LF,UP,'`',LF,UP,'`',RT,DN,0}; int phi[] {'o','/',0}; int PHI[] {'o','[',']',0}; int psi[] {'/','-',DN,DN,RT,RT,'\'',-4,LF,'\'',RT,RT,UP,UP,0}; int PSI[] {'[',']','-',DN,DN,RT,RT,'\'',-4,LF,'`',RT,RT,UP,UP,0}; int pi[] {UP,'-',-3,DN,'"',DN,'"',-3,UP,0}; int PI[] {LF,LF,'[',']',-4,RT,'[',']',LF,LF,-3,UP,'-',-3,DN,0}; int rho[] {'o',LF,LF,DN,DN,'|',UP,UP,RT,RT,0}; int sigma[] {'o',DN,RT,RT,'~',UP,LF,LF,0}; int SIGMA[] {'>',-2,DN,'-',-5,UP,'-',-3,DN,0}; int tau[] {'t',DN,RT,RT,'~',LF,LF,LF,'~',RT,UP,0}; int theta[] {'O','-',0}; int THETA[] {'O','=',0}; int xi[] {'c',RT,DN,',',LF,-3,UP,'c',LF,DN,'`',RT,DN,0}; int zeta[] {'c',RT,DN,',',LF,-3,UP,'<',DN,DN,0}; int tab[]{ 'A', /* alpha */ 'B', /* beta */ 'D', /* delta */ 'W', /* DELTA */ 'S', /* epsilon */ 'N', /* eta */ '\\', /* gamma */ 'G', /* GAMMA */ 'o', /* infinity - not in M37 */ '^', /* integral */ 'L', /* lambda */ 'E', /* LAMBDA */ 'M', /* mu */ '[', /* nabla (del) */ '_', /* not */ '@', /* nu */ 'C', /* omega */ 'Z', /* OMEGA */ ']', /* partial */ 'U', /* phi */ 'F', /* PHI */ 'V', /* psi */ 'H', /* PSI */ 'J', /* pi */ 'P', /* PI */ 'K', /* rho */ 'Y', /* sigma */ 'R', /* SIGMA */ 'I', /* tau */ 'T', /* theta */ 'O', /* THETA */ 'X', /* xi */ 'Q', /* zeta */ 0 }; int trans[]{ alpha, beta, delta, DELTA, epsilon, eta, gamma, GAMMA, infinity, integral, lambda, LAMBDA, mu, nabla, not, nu, omega, OMEGA, partial, phi, PHI, psi, PSI, pi, PI, rho, sigma, SIGMA, tau, theta, THETA, xi, zeta, 0 }; special(){ int c,i,j,t; loop: if( (c=getchar()) == SI ) return; for( i=0; tab[i]!=0; i++) if( c==tab[i] ){ plot(trans[i]); goto loop; } putchar(c); goto loop; } plot(s) int *s; { int i,c; enterplot; for( i=0; (c=s[i])!=0; i++ ) if( c<0 ) nplot(-c,s[++i]); else nplot(1, c); leaveplot; putchar(' '); } nplot(n,c) int n,c; { while(n--) { if( c == UP ) putchar(ESC); putchar(c); } } psi, PSI, pi, PI, rho, sigma, SIGMA, tau, theta, THETA, xi, zeta, 0 }; special(){ int c,i,j,t; loop: if( (c=getchar()) == SI ) return; for( i=0; tab[i]!=0; i++) if( c==tab[i] ){ plot(trans[i]); goto loop; } putchar(c); goto loop; } plot(s) int *s; { int i,c; enterplot; for( i=0; (c=s[i])!=0; i++ ) if( c<0 ) nplot(-c,s[++i]); else nplot(1,char b[242]; char c[60]; int nread 1; char buf[512]; main(argc,argv) int argc; char *argv[]; { int l,isw,k,ifile,i,j; if(--argc <= 0) {ifile = 0; argc = 0; goto newl; } l = 1; while(argc--) {printf("%s:\n \n",argv[l]); ifile = open(argv[l++],0); if(ifile < 0) {printf("cannot open input file\n"); exit(); } newl: isw = j = 0; i = -1; cont: while((b[++i] = get(ifile)) != 0) {if((b[i] >= 'a' && b[i] <= 'z') || (b[i] >= 'A' && b[i] <= 'Z')) {c[j++] = b[i]; goto cont; }  if(b[i] == '-') {c[j++] = b[i]; if((b[++i] = get(ifile)) != '\n') {c[j++] = b[i]; goto cont; } if(j == 1)goto newl; isw = 1; i = -1; while(((b[++i] = get(ifile)) == ' ') || (b[i] == '\t') || (b[i] == '\n')); c[j++] = b[i]; goto cont; } if(b[i] == '\n'){if(isw != 1)goto newl; i = -1; } if(isw == 1) {k = 0; c[j++] = '\n'; while(k < j)putchar(c[k++]); } isw = j = 0; } } } get(ifile) int ifile;{ static char *ibuf; if(--nread){ return(*ibuf++);} if(nread = read(ifile,buf,512)){ if(nread < 0)goto err; ibuf = buf; return(*ibuf++); } nread = 1; return(0); err: nread = 1; printf("read error\n"); return(0); } \t') || (b[i] == '\n')); c[j++] = b[i]; goto cont; } if(b[i] == '\n'){if(isw != 1)goto newl; i = -1; } if(isw == 1) {k = 0; c[j++] = '\n'; while(k < j)putchar(c[k++]); } isw = j = 0; } } } get(ifile) int ifile;{ static char *ibuf; if(--nrea# #define CLEAR 021 #define DSTATE 020 #define FSTATE 001 #define ALLINUM inum=1;inum<=imax;inum++ #define ALLAP ap= &inode->addr[0];ap<&inode->addr[8];ap++) if (*ap #define ALLOC (inode->flags&0100000) #define LARGE (inode->flags&010000) #define DIR ((inode->flags&060000)==040000) #define NOTSPL ((inode->flags&020000)==0) #define MAXDUP 100 struct SB { int isize; int fsize; int nfree; int free[100]; int ninode; int finode[100]; char flock; char ilock; char fmod; int time[2]; int fill[50]; } sb; struct INODE { int flags; char nlinks; char uid; char gid; char size0; int size1; int addr[8]; int actime[2]; int modtime[2]; } *inode; struct DE { int dnum; char dname[14]; }; struct {int INT;}; char *bbit, *fbit, *state, *lc, pathname[200], *pp, *name, *fmin, *fmax, sflag, nflag, yflag, *dev, ; int n_free, n_blks, n_files, inum, diskr, diskw, cc, dups[MAXDUP], *dc, *el, imax, imod, mod, dmod, buf[256], ttyargs[3], ; main(argn,argv) int argn; char *argv[]; { char c,lsflag,lnflag,lyflag; int i; gtty(0,ttyargs); lyflag = lnflag = lsflag = 0; chdir("/dev"); sync(); if(argn==1) { check(dev="rootdev"); goto fin; } for(i=1;i>3)&017777)+1); fbit = state = sbrk(imax/4+1); lc = sbrk(imax+1); el = dc = dups; n_files = n_blks = n_free = *dc = 0; pp = pathname; pathname[0] = '/'; pathname[1] = 0; /* Phase 1 */ printf("Phase 1 - Check Blocks\n"); for(ALLINUM) { stat(); if(ALLOC) { n_files++; if(DIR) set(DSTATE); else set(FSTATE); if((lc[inum]=inode->nlinks)==0) set(CLEAR); if(NOTSPL)for(ALLAP) if(pass1(*ap) && LARGE) iblock(*ap,&pass1); } } /* Phase 2 */ setexit(); if(dc==dups) goto phase3; printf("Phase 2 - Rescan for more DUPS\n"); for(ALLINUM) if(get()) { stat(); if(NOTSPL)for(ALLAP) if(pass2(*ap) && LARGE) iblock(*ap,&pass2); } /* Phase 3 */ phase3: printf("Phase 3 - Check Pathnames\n"); inum = 1; lc[1]++; descend(); /* Phase 4 */ printf("Phase 4 - Check Reference Counts\n"); for(ALLINUM) switch(get()) { case FSTATE: if(lc[inum]) adj(); continue; case DSTATE: case CLEAR: clri(); } stat(imax+1); /* Phase 5 */ if (sflag) goto salvage; printf("Phase 5 - Check Free List\n"); brk(cp=fbit+(((fmax>>3)&017777)+1)); bp = bbit; for(ap=fbit;ap100) goto bad; while(blk = sb.free[--sb.nfree]) { if(sb.nfree==0) { if(seek(diskr,blk,3) < 0) rwerr("SEEK",blk); if(read(diskr,&sb.nfree,202)<0) rwerr("READ",blk); } if(sb.nfree<=0 || sb.nfree>100) goto bad; if(blk=fmax || (fbit[a=((blk>>3)&017777)]&(b=1<<(blk&07)))) { bad: printf("%15s %-15s\tSALVAGE?","","BAD FREE LIST"); sflag = reply(); goto salvage; } fbit[a] =| b; n_free++; } if((n_blks+n_free)!=(fmax-fmin)) { printf("%15l %-15s\tSALVAGE?",fmax-fmin-n_blks-n_free, "MISSING"); sflag = reply(); } /* Phase 6 */ salvage: if(sflag==0) goto statistic; printf("Phase 6 - Salvage Free List\n"); n_free = sb.ninode = sb.nfree = 0; sb.free[sb.nfree++] = 0; for(blk=fmax-1;blk>=fmin;--blk) if((bbit[(blk.INT>>3)&017777]&(1<<(blk&07)))==0) { if(sb.nfree==100) { if(nflag==0) { if(seek(diskw,blk,3)<0) rwerr("SEEK",blk); if(write(diskw,&sb.nfree,512)<0) rwerr("WRITE",blk); } sb.nfree = 0; } sb.free[sb.nfree++] = blk; n_free++; } if(nflag==0) { if(seek(diskw,1,3)<0) rwerr("SEEK",1); if(write(diskw,&sb,512)<0) rwerr("WRITE",1); mod = 1; } statistic: printf("%5l files %5l blocks %5l free\n", n_files,n_blks,n_free); close(diskr); close(diskw); } pass1(blk) char *blk; { register int a,b,*ip; if(blk=fmax) { blkerr("BAD",blk); return(0); } if(bbit[a=((blk>>3)&017777)]&(b=(1<<(blk&07)))) { blkerr("DUP",blk); if(el > &dups[MAXDUP]) { printf("\tEXCESSIVE DUPS EXIT?"); if(reply()) exit(); else goto ret; } ip = dups; while(ip=fmax) return(0); ip = dups; while(ip<dc) if(*ip++ == blk) { blkerr("DUP",blk); *--ip = *--dc; *dc = blk; if(dc==dups) reset(); else break; } return(1); } stat() { static struct INODE ibuf[16]; static int cib; register int ib; if((ib=2+(inum-1)/16)!=cib) { if(imod && (nflag==0)) { if(seek(diskw,cib,3)<0) rwerr("SEEK",cib); if(write(diskw,ibuf,512)<0) rwerr("WRITE",cib); imod = 0; mod = 1; } if(seek(diskr,cib=ib,3) < 0) rwerr("SEEK",cib); if(read(diskr,ibuf,512)<0) rwerr("READ",cib); } return(inode = &ibuf[(inum-1)%16]); } iblock(blk,func) char *blk,(*func)(); { register int *ap; ap = buf; do { getblk(blk); if(*ap) (*func)(*ap); } while(++ap<&buf[256]); } blkerr(s,blk) char *blk; char *s; { printf("%15l %-15s I = %l\n",blk,s,inum); set(CLEAR); } clri() { register int *ap; stat(); printf("%15s %-15sI = %5l\tCLEAR?", ((inode->nlinks==0)||(get()!=CLEAR))?"UNREFERENCED":"BAD/DUP", DIR?"DIRECTORY":"FILE",inum); if(reply()) { n_files--; if(NOTSPL)for(ALLAP) if(pass4(*ap) && LARGE) iblock(*ap,&pass4); for(ap=inode;ap<&inode[1];*ap++ = 0); imod = 1; } } pass4(blk) char *blk; { register int a,b,*ip; if(blk=fmax) return(0); if(bbit[a=((blk>>3)&017777)]&(b=1<<(blk&07))) { ip = dups; while(ipnlinks==lc[inum]) clri(); else { printf("%15s %-15sI = %5l\tADJUST?", "LINK COUNT",DIR?"DIRECTORY":"FILE",inum); if(reply()) { inode->nlinks =- lc[inum]; imod = 1; } } } descend() { register int *ip,*ap; int a[8]; extern int pass3(); char *lname; if(inum>imax) return(direrr("I OUT OF RANGE")); again: switch(get()) { case DSTATE: set(FSTATE); lc[inum]--; ip = &stat()->addr[0]; for(ap=a;ap<&a[8];) *ap++ = *ip++; *pp++ = '/'; lname = name; name = pp; if(LARGE) { for(ap=a;ap<&a[8];ap++) if(*ap) iblock(*ap,&pass3); } else { for(ap=a;ap<&a[8];ap++) if(*ap) pass3(*ap); } name = lname; *--pp = 0; return(0); case FSTATE: lc[inum]--; return(0); case 0: return(direrr("UNALLOCATED")); case CLEAR: if(direrr("DUP/BAD")) return(1); stat(); if(DIR) set(DSTATE); else set(FSTATE); goto again; } } pass3(blk) char *blk; { register struct DE *dp; register char *c; dp = buf; do { getblk(blk); if(inum = dp->dnum) { c = &dp->dname[0]; while((*pp = *c++) && pp++ && c<&dp->dname[14]); *pp = 0; if(descend()) { getblk(blk); dmod = 1; dp->dnum = 0; } pp = name; } } while(++dp<&buf[256]); } direrr(s) char *s; { printf("%15s I = %-5l%s\tREMOVE?",s,inum,pathname); return(reply()); } reply() { register char c; if(nflag) { printf(" no\n"); return(0); } if(yflag) { printf(" yes\n"); return(1); } do c = getchar(); while(c == ' ' || c == '\t'); stty(0,ttyargs); printf("\n"); if(c == 'y') return(1); else return(0); } putchar(c) char c; { if(c) write(1,&c,1); } getchar() { char c; read(0,&c,1); return(c); } rwerr(s,b) char *s,*b; { printf("\nCAN NOT %s: %s\tBLOCK %5l\tEXIT?",s,dev,b); if(nflag || reply()) { printf("\n\n"); exit(); } } getblk(blk) char *blk; { static char *cb; if(blk==cb) return; if(dmod && (nflag==0)) { if(seek(diskw,cb,3)<0) rwerr("SEEK",cb); if(write(diskw,buf,512)<0) rwerr("WRITE",cb); dmod = 0; } if(seek(diskr,cb=blk,3)<0) rwerr("SEEK",blk); if(read(diskr,buf,512)<0) rwerr("READ",blk); } ar c; { if(c) write(1,&c,1); } getchar() { char c; read(0,&c,1); return(c); } rwerr(s,b) char *s,*.text .globl _set,_get,_inum,_state,_brk,_sbrk,_nd,_end _set: mov _inum,r0 mov r0,r1 ash $-2,r1 add _state,r1 bic $!3,r0 bicb m(r0),(r1) mov r1,-(sp) mov 4(sp),r1 ash r0,r1 bisb r1,*(sp)+ rts pc m: .byte 0021,0042,0104,0210 _get: mov _inum,r0 mov r0,r1 ash $-2,r0 add _state,r0 movb (r0),r0 bic $!3,r1 neg r1 ash r1,r0 bic $!021,r0 rts pc _brk: clr _nd _sbrk: mov _nd,r0 add 2(sp),_nd bit $1,_nd beq 1f inc _nd 1: sys 0;0f rts pc .data 0: sys break;_nd:_end .text (s,b) char *s,*# /* if command */ /* * status codes */ # define GOOD "0" # define SOMEBAD "4" # define ALLBAD "8" int ap; int ac; char **av; main(argc, argv) char *argv[]; { argv[argc] = 0; ac = argc; av = argv; ap = 1; if (argc<2) return; if (exp()) if(doex(0)) { write(1, "no command\n", 11); seek(0, 0, 2); } } char *nxtarg() { if (ap>ac) return(0*ap++); return(av[ap++]); } exp(s) { int p1; p1 = e1(); if (eq(nxtarg(), "-o")) return(p1 | exp()); ap--; return(p1); } e1() { int p1; p1 = e2(); if (eq(nxtarg(), "-a")) return (p1 & e1()); ap--; return(p1); } e2() { if (eq(nxtarg(), "!")) return(!e3()); ap--; return(e3()); } e3() { int p1, ccode; register char *a, *b; char *getn(); ccode = 0; if ((a=nxtarg())==0) goto err; if(eq(a, "(")) { p1 = exp(); if(!eq(nxtarg(), ")")) goto err; return(p1); } if(eq(a, "-r")) return(tio(nxtarg(), 0)); if(eq(a, "-w")) return(tio(nxtarg(), 1)); if(eq(a, "-c")) return(tcreat(nxtarg())); if(eq(a, "{")) { /* execute a command for exit code */ if(fork()) /*parent*/ wait(&ccode); else { /*child*/ doex(1); goto err; } while((a=nxtarg()) && (!eq(a,"}"))); a=nxtarg(); if((eq(a,SOMEBAD)) || (eq(a,ALLBAD)) || (eq(a,GOOD)) ) { return((ccode>>8)<=getn(a)? 1 : 0); } else ap--; return (ccode>>8 ? 0 : 1); } p1 = nxtarg(); if (p1==0) goto err; if(eq(p1, "=")) return(eq(a, nxtarg())); if(eq(p1, "!=")) return(!eq(a, nxtarg())); err: write(1, "if error\n", 9); exit(9); } tio(a, f) { a = open(a, f); if (a>=0) { close(a); return(1); } return(0); } tcreat(a) { return(1); } eq(a, b) char *a, *b; { register int i; i = 0; l: if(a[i] != b[i]) return(0); if(a[i++] == '\0') return(1); goto l; } char *getn(bp) char *bp; { register int n, c; register char *p; p = bp; n = 0; while ((c = *p++) >= '0' && c <= '9') n = n*10 + c - '0'; return(n); } doex(earg) { register int np, i, c; char *nargv[50], *ncom, *na; np = 0; while (na=nxtarg()) { if(earg && eq(na,"}")) break;  nargv[np++] = na; } if(earg && (!eq(na, "}"))) return(9); nargv[np] = 0; if (np==0) return(earg); execv(nargv[0], nargv, np); i = 0; ncom = "/usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; while(c=nargv[0][i]) { ncom[9+i++] = c; } ncom[9+i] = '\0'; execv(ncom+4, nargv, np); execv(ncom, nargv, np); return(1); } & c <= '9') n = n*10 + c - '0'; return(n); } doex(earg) { register int np, i, c; char *nargv[50], *ncom, *na; np = 0; while (na=nxtarg()) { if(earg && eq(na,"}")) break; #define CSPEED (07<<8)|07 #define XTABS 02 #define LCASE 04 #define ECHO 010 #define CRMOD 020 #define ANYP 0300 #define CR1 010000 #define NPROC 50 #define NOFILE 15 #define SINGLE 7 #define REBOOT ~7 #define BUFSIZ 512 #define NTOKEN 5 #define NARGS 20 #define IPROCSZ 3 #define SIGHUP 1 #define LVL0 2 #define LVL1 3 #define LVL2 4 #define LVL3 5 #define LVL4 6 #define LVL5 7 #define LVL6 8 #define KILL 9 #define SINLVL 10 #define SIGSEG 11 #define SIGSYS 12 #define SIGPIPE 13 #define SIGCLK 14 #define SIGWRN 15 #define ARESPAWN 21 #define AONCE 22 #define AWAIT 23 #define AOFF 24 #define ABOOT 25 #define ABOOTWAIT 26 #define ADEMAND 27 struct entryln { char *lid; char *rlevel; char *action; char *shellcm; char **initcm; }l; struct iproc { int id; char flip; char flop; int ipid; } iproc[NPROC]; struct stimulus { char *keystr; int numb; }; struct utmp { char name[8]; int line; int time[2]; int upid; }utmp; int catchit,hboot,il,iq,rb,status; int curlvl,lvltag,wrncnt; char lbuf[BUFSIZ+1]; char *inarg[NARGS+1]; char *CTTY "/dev/ln00"; char *SUSER "/bin/sh"; char *LINES "/etc/lines"; char *GETTY "/etc/getty"; char *SHELL "/bin/sh"; char *INIT "/etc/init"; char *UTMPF "/etc/utmp"; char *WTMPF "/etc/wtmp"; char *XINIT "/etc/xinit"; char set 1; struct stimulus siggrp[] { "0",LVL0, "1",LVL1, "2",LVL2, "3",LVL3, "4",LVL4, "5",LVL5, "6",LVL6, "a",SIGSEG, "b",SIGSYS, "c",SIGPIPE, 0 }; struct stimulus action[] { "respawn",ARESPAWN, "once",AONCE, "wait",AWAIT, "off",AOFF, "boot",ABOOT, "bootwait",ABOOTWAIT, "ondemand",ADEMAND, 0 }; char *tabu[]{ "xx", "RL", "!B", "OT", "NT", 0 }; int cpackit[]{ CSPEED, 0, ANYP+XTABS+LCASE+CRMOD+ECHO+CR1 }; main() { register i,runlvl,pid; setsig(); lvltag = 0; i = creat(UTMPF,0644); copy("RL",&utmp.line); /*initialize "RL" slot in UTMPF*/ write(i,&utmp,16); close(i); acctg(-10,"**BOOT**"); /*record boot time*/ if((i=getcsw()) == SINGLE) single(); if(lvltag == 0){ i = getcsw() + 2; /* run level = signal-2 */ if(i>=LVL0 && i<=LVL6) lvltag = i; else lvltag = LVL0; } /* * Main process path---steady state condition. */ for(hboot=0;;) { setexit(); sync(); runlvl = 0; if(lvltag){ runlvl = lvltag; lvltag = 0; } switch(runlvl){ case 0: /*death of a child -rescan lines file*/ case SIGHUP: /*immediate scan of lines file*/ runlvl = curlvl; break; default: if(runlvl>=LVL0 && runlvl<=LVL6) if(runlvl != curlvl) if(cleanup(runlvl)) continue; /*err in cleanup*/ } bringup(runlvl); sync(); if(lvltag && lvltag != SINLVL) continue; for(;;){ pid = wait(&status); if(pid == -1){ /*a signal was caught*/ if(lvltag == SINLVL) { lvltag = 0; continue; } break; } if((i=find(pid,0))<0)continue; /*not in proc table*/ rmproc(i); break; /* iproc[i].flip == 0 ---rescan lines file and start up entry line process */ } } } /* * If the run level is between LVL0 and LVL6, * cleanup will post a 20 second warning to all processes * running at a run level that is no longer current. If * the warned process does not gracefully exit after 20 seconds * have elapsed,the errant process is forcibly terminated. * If runlvl is null then all processes in INIT's process * table will be posted a 20 second warning and subsequently will * terminate or be terminated. * No other runlvls are possible. */ cleanup(runlvl) { register int *wptr; register char *sptr; register pid; int i,j; int warnid[NPROC]; if(openlns()) { if(runlvl) single(); return(1); /*error return*/ } wrncnt = 0; wptr = &warnid; zero(wptr,NPROC); loop: while(j=getline()){ if(j<0)continue; zmap(); if((il=find(l.lid,1)) < 0) continue; if((l.rlevel == 0) && runlvl) continue; /*null field case*/ if(runlvl){ /*check run level*/ for(sptr=l.rlevel; *sptr; sptr++) { i = *sptr; i =& 0177; if((i=stoi(&i,&siggrp)) == 0) { console("Illegal rlevel at %s\n",l.lid); goto loop; } if(i == runlvl) goto loop; } } if(kill(iproc[il].ipid,SIGWRN) < 0) zero(&iproc[il].id,IPROCSZ); else{ wrncnt++; *wptr++ = iproc[il].ipid; iproc[il].flip = 20; } } alarm(20); while(wrncnt) { pid = wait(&status); if((pid != -1) && ((j=find(pid,0)) != -1)) { if(iproc[j].flip == 20 && wrncnt) --wrncnt; rmproc(j); } } alarm(0); for(wptr = &warnid; (*wptr && (wptr <= wptr[NPROC])); wptr++) { if((j=find(*wptr,0)) != -1) killproc(j); } close(0); return(0); /*successful cleanup*/ } /* * Legal runlvls honored by bringup are those falling * between LVL0 and LVL6 and between SIGSEG and SIGPIPE. * All others are invalid. */ bringup(runlvl) { int i; register j; register char *sptr; if(openlns()) { single(); return(1); } set =* -1; while(j=getline()){ if(j<0)continue; /* bad entry - ignore */ if((iq = find(0,0)) < 0) { /*index for free slot*/ console("INIT process table filled(> %d)\n",NPROC); close(0); sleep(20); return(0); } zmap(); /* zero out pointers pointing to nulls */ il = find(l.lid,1); /* index for this process */ if(il >= 0){ /*process exists*/ iproc[il].flop = set; if(nullchk()) continue; } else{ /*process not in iproc table*/ if(nullchk()){ l.action = "respawn"; copy(GETTY,&lbuf[4]); /*save l.lid ref*/ for(j=4;lbuf[j];j++); /*find end of str*/ lbuf[j++] = ' '; /*pad w/blank*/ copy("ln",&lbuf[j]); j =+ 2; copy(l.lid,&lbuf[j]); /*append line id*/ l.initcm = &lbuf[4]; dfork(iq); continue; } } if(l.rlevel){ /*run level dependent entry*/ for(sptr = l.rlevel; *sptr; sptr++) { i = *sptr; i =& 0177; if((i=stoi(&i,&siggrp)) == 0) { console("Illegal rlevel at %s\n",l.lid); break; } if(i == runlvl) goto ground; } if(il>=0 && runlvl>=LVL0 && runlvl<=LVL6) wrnkill(il); continue; } ground: if((i=stoi(l.action,&action)) == 0) { console("Illegal action at %s\n",l.lid); continue; } aloop(i,runlvl); } close(0); for(j=0;j=LVL0 && runlvl<=LVL6 && curlvl != runlvl){ acctg(-runlvl,"RUNLEVEL"); /*record run level*/ curlvl = runlvl; /* reset the current level */ } if(hboot == 0) hboot = 1; if(catchit) {/* catches secondary child deaths */ catchit = 0; reset(); } return(0); } /* * Interpret action field and perform the predefined * actions. */ aloop(actnum,runlvl) { register i; switch(actnum) { case ADEMAND: case ARESPAWN: /* start the process and do not wait for its completion */ if(il<0) dfork(iq); /* create a process */ return; /* ignore--process is alive */ case AONCE: /* start the process once and clear it from init's process table when it dies */ if(curlvl == runlvl) return; dfork(iq); return; case AWAIT: /* start the process and wait for it! */ if(curlvl == runlvl) return; waitfor(iq); return; case AOFF: /* Ignore this process and continue on. if process is active then terminate it and clear the entry from the proc table. A 20 second warning is posted before it is forcibly terminated. */ if(il < 0) return; wrnkill(il); return; case ABOOT: /* start this process only at boot time ignore on any subsequent scan of this */ if(hboot == 0) dfork(iq); return; case ABOOTWAIT: /*same as ABOOT but wait for it*/ if(hboot == 0) waitfor(iq); return; } } /* * Wait for the process to complete */ waitfor(enum) { dfork(enum); if(waitproc(iproc[enum].ipid)) rmproc(enum); } /* * Create/re-create processes via a fork. * Parent process stores in the proc table the process id of the * child and the entry tag(lid). * The parent then returns without waiting for the child to complete. */ dfork(enum) { register char **reserve; register char *atty; register type; type = -1; if(enum < 0) { console("%d is an invalid iproc table entry\n",enum); return; } if(l.shellcm) type = 0; if(l.initcm){ type = 2; getarg(); if(cmp(*l.initcm,GETTY)) { for(reserve=tabu;*reserve;reserve++){ if(cmp(l.lid,*reserve) == 0) continue; console("line id %s reserved\n",l.lid); return; } type = 1; } } copy(l.lid,&iproc[enum].id); iproc[enum].flip = 0; iproc[enum].flop = set; if((iproc[enum].ipid = fork()) == 0) { close(0);close(1);close(2); if(l.shellcm) shcmnd(); if(l.initcm) incmnd(); exit(1); } switch(type){ case 0: acctg(enum,l.shellcm); break; case 1: acctg(enum,1); break; case 2: acctg(enum,*l.initcm); } } /* * The shell command interpreter is invoked with the * '-c' option. */ shcmnd() { register i; if((i=fork()) == 0) { open("/dev/null",0); open(CTTY,1); stty(1,cpackit); execl("/bin/sh","-","-c",l.shellcm,0); console("%s not executed\n",l.shellcm); sleep(20); exit(1); } waitproc(i); } /* * A check is performed on the first character of an argument field * to see if the standard input and output is to be changed. * If it is then a change is initiated and the process is * executed. Incmnd assumes that the process and its arguments * are in a vector beginning at inarg. */ incmnd() { register char **k,*infile,*outfile; k = l.initcm; while(*k) { switch(**k) { case '<' : /* change standard input */ if(k[0][1] == 0){ *k++ = 0; infile = *k; } else infile = ++(*k); *k++ = 0; close(0); if((open(infile,2)) < 0){ console("bad input file %s:%s\n", l.lid,infile); sleep(20); exit(1); } break; case '>' : /* change standard output */ if(k[0][1] == 0){ *k++ = 0; outfile = *k; } else outfile = ++(*k); *k++ = 0; close(1); switch(open(outfile,2)) { case 0: dup(0); close(0); break; case -1: console("bad out file %s:%s\n", l.lid,outfile); sleep(20); exit(1); } break; default : k++; } } execv(*l.initcm,l.initcm); console("%s not executed\n",*l.initcm); sleep(20); } /* * Invoke single user mode on the console tty. */ single() { register i,j; curlvl = rb = 0; if(lvltag) clrsys(); acctg(-1,"RUNLEVEL"); /*single user recording*/ for(;;) { console("SINGLE USER MODE\n"); if((rb=fork()) == 0) { close(0);close(1);close(2); open(CTTY,2); dup(0); stty(1,cpackit); execl(SUSER,"-",0); console("Exec of %s failed\n",SUSER); exit(1); } while(rb != (j=wait(&status))) { if(j == -1){ if(lvltag>=LVL0 && lvltag <= LVL6){ kill(rb,KILL); if(hboot) reset(); return; } lvltag = 0;  } } if((i=bus()) != SINGLE && i != REBOOT){ i =+ 2; if(i>=LVL0 && i<=LVL6) lvltag = i; else lvltag = LVL0; if(hboot) reset(); return; /*valid only at boot time*/ } } } /* * The bus signal (10) is trapped to this function. * The console switches are checked and either the * single user or reboot sequence is started up. */ bus() { register j; register struct iproc *p; signal(lvltag=SINLVL,bus); switch(j=getcsw()){ case SINGLE: if(curlvl) single(); break; /*if already in single user*/ case REBOOT: if(curlvl){ console("Not single user-reboot disallowed\n"); break; } clrsys(); if(rb)kill(rb,KILL); /*kill SU console tty*/ console("Overlay with %s\n",XINIT); sleep(5); /*delay for switch setting chng*/ execl(XINIT,XINIT,0); console("Overlay with %s failed\n",XINIT); if(rb == 0) single(); break; } return(j); } /* * Record the accounting information on all processes * when they spawn and die. the utmpf file will always have * an instantaneous record of process activities; while the wtmpf * file(if it is turned on) will contain the running history of * the process activities from the time WTMPF file was turned on. * ENUM MARKER REASON * >=0 0 dead process * >=0 1 line process * >=0 string non-line process * -1 RUNLEVEL single user * -(2->8) RUNLEVEL run levels * -10 **BOOT** hardware boot */ acctg(enum,marker) char *marker; { register rw,k; register struct utmp *p; int cbuf[256]; char *cp; int key; zero(&utmp,(sizeof utmp)/2); switch(marker){ default: /*non-line process accounting*/ cp = marker; while(*cp) /*strip off leading pathnames*/ if(*cp++ == '/') marker = cp; copy(marker,utmp.name); if(enum < 0){ if(enum == -10){ copy("!B",&key); utmp.upid = 0; } else{ /*(-1,-8)*/ copy("RL",&key); if(enum != -1) enum = -(enum) - 2; utmp.upid = enum; } break; } case 1: /*line process accounting*/ utmp.upid = iproc[enum].ipid; case 0: /*dead process accounting*/ key = iproc[enum].id; } utmp.line = key; time(utmp.time); if((rw=open(UTMPF,2)) < 0) goto out; while((k=read(rw,&cbuf,512)) > 0){ cp = k; /*save original count*/ for(p = &cbuf;(k =- 16) >= 0; p++){ /*does it exist?*/ if(p->line != key) continue; seek(rw,-(k+16),1); write(rw,&utmp,16); goto out; } if(cp < 512) break; /*entire utmpf file examined*/ } seek(rw,0,0); while((k=read(rw,&cbuf,512)) > 0){ cp = k; /*save original count*/ for(p = &cbuf;(k =- 16)>=0; p++){ /*look for empty slot*/ if(p->line != 0) continue; seek(rw,-(k+16),1); write(rw,&utmp,16); goto out; } if(cp < 512) break; } if(k <= 0) write(rw,&utmp,16); /* boundary case conditions * where '<' implies the end * of the file but < 512 */ out: close(rw); if((rw=open(WTMPF,1)) >= 0) { seek(rw,0,2); write(rw,&utmp,16); close(rw); } sync(); } /* * Lines file opening strategy */ openlns() { register i; switch(i=open(LINES,0)){ case 0: break; default: close(i); sleep(1); switch(i=open(LINES,0)){ case 0: break; default: close(i); sleep(3); switch(i=open(LINES,0)){ case 0: break; default: close(i); console("open error on %s\n",LINES); return(1); } break; } break; } return(0); /*successful open*/ } /* * Getline filters out comments,maps multiple blanks to one * blank and stores into a previously nulled-out 5 element array * pointers to non-null fields(defined as tokens between colons on * the entry line). Getline parses an entry until a line feed is * encountered and subsequently returns a 1. A -1 is returned on * a syntax infraction and a 0 on the end of file for /etc/lines. */ getline() { register char c,*q; register int *p; char c0; int fl,keepc; fl = 1; zero(&lbuf,BUFSIZ/2); /* zero out lbuf char array(512) */ zero(&l,NTOKEN); /* zero out array of pointers -struct "l" */ p = &l; q = &lbuf; keepc = ' '; *p = q; while((c = getchar()) > 0) { if(q > &lbuf[BUFSIZ]) { console("%d buffer size exceeded\n",BUFSIZ); while((c=getchar()) != '\n'); /*goto end of line*/ return(-1); } switch(c) { case'/': /* comments */ c0 = comments(); if(c0 == 0)return(-1); if(c0 == '\n'){ *q++ = c; goto err; } if(c0 != '*'){ *q++ = c; *q++ = c0; } continue; case ':': if(fl == 1 && q>(&lbuf[2])) goto err; *q = '\0'; *(++p) = ++q; keepc = ' '; if(fl++ > NTOKEN) { console("over %d token limit\n%s\n", NTOKEN,&lbuf); goto err; } continue; case '\n': /* end of line or continuation */ if(keepc == '\\') { q--; continue; } *q = '\0'; if(fl == 1) goto err; return(1); case '\t': /* suppress horiz tabs */ continue; case ' ': /* all excess blanks reduced to one*/ if(keepc == ' ') continue; default: *q++=c; keepc = c; } } return(0); err: console("syntax violation in LINES file entry at %s\n",l.lid); return(-1); } /* * supress comments in lines files */ comments() { register char c; if((c=getchar())!='*')return(c); while((c=getchar())>0) if(c=='*' && (c=getchar())=='/')return('*'); console("syntax violation at %s\n",l.lid); return(0); } /* * Parsing a given token with delimiters '\0',' '. * Pointers to the various arguments in the initcm token * fields are stored in an array of pointers(inarg). * Because of getline's parsing no more than one * blank between characters exist. */ getarg() { register char *s; register int *d,ctr; ctr = 1; d = &inarg; /*ptr to array of argument ptrs*/ s = l.initcm; /* ptr to lbuf[] element */ l.initcm = d; zero(inarg,NARGS); /* zero out array of pointers */ *d++ = s; while(*s) { switch(*s) { case ' ': *s++ = '\0'; *d++ = s++; if(ctr++ > NARGS) { console("%d args exceeded\n",NARGS); console("%s not executed\n",*l.initcm); return(-1); } break; default: s++; } } } /* * Close all files and clear the system with due warning */ clrsys() { register i; for(i=0;i=0) rmproc(enum); } /* * The process id is passed to waitproc and a wait is effected * until a process id or a signal is caught. If the object * process dies a 1 is returned, if a signal is caught a 0 is returned. * if a secondary process(other than the desired process in question) * dies waitproc checks if it is one of INIT's child and if it is * removes it, sets the catchit flag and continues to wait. * If the process is not a child of INIT then it just continues * to wait. */ waitproc(pnum) { register i; while((i=wait(&status)) != pnum){ if(i<0) return(0); /*a signal was caught*/ if((i=find(i,0)) < 0) continue; ++catchit; /*secondary process died*/ rmproc(i); } return(1); /*successful wait on primary process*/ } /* * process is removed from init's internal process table */ rmproc(enum) { if(iproc[enum].ipid){ acctg(enum,0); zero(&iproc[enum].id,IPROCSZ); } } /* If a pointer addresses a value of zero(\0) then that * pointer is zeroed out. */ zmap() { register i; register char **k; k = &l; k++; /* begin at l.rlevel (offset 1) */ for(i=0; iid == value)return(i); return(-1); } /* * Check the l.rlevel,l.action,l.shellcm and l.initcm fields * for null values. If they are all null then return 1. */ nullchk() { register i,j,*k; k = &l; j = 0; k++; /* begin at offset 1 */ for(i=0;inumb;b++) if(cmp(a,b->keystr)) return(b->numb); return(0); } /* * 1 = successful string compare * 0 = failure on string compare */ cmp(a,b) char *a,*b; { while(*a++ == *b) { if (*b++ == '\0') return(1); } return(0); } /* * copy string s to string t */ copy(s,t) char *s,*t; { while(*t++ = *s++); } /* * Zeroes out the given array. Note where character arrays * are involved the limit passed must be one-half the size * of the target array. */ zero(array,limit) int *array; { register i; for(i=0; i 1) { argv++; argc--; if(stat(*argv, sb) < 0) sb[1] = 0; printf("%5l %s\n", sb[1], *argv); } flush(); } = SIGHUP,hangup);} intr() { signal(lvltag = LVL0,intr);} quit() { signal(lvltag = LVL1,quit);} ilgins() { signal(lvltag = LVL2,ilgins);} trace() { signal(lvltag = LVL3,trace);} iot() { signal(lvltag = LVL4,iot);} emt() { signal(lvltag = LVL5,emt);} fpt() { signal(lvltag = LVL6,fpt);} seg() { sign# int tflg; int iflg; int aflg; int sflg; struct { char name[8]; int type; int value; } nl[] { "_dk_busy", 0, 0, "_rfintr", 0, 0, "_rkintr", 0, 0, "_rpintr", 0, 0, "_hpintr", 0, 0, "_hsintr", 0, 0, "\0\0\0\0\0\0\0\0", 0, 0 }; #define IRF 1 #define IRK 2 #define IRP 3 #define IHP 4 #define IHS 5 struct { int busy; long etime[32]; long numb[3]; long wds[3]; long tin; long tout; } s, s1; double etime; double xf[] { 16.0, 11.1, 7.5, }; char *device[] { 0, 0, 0, 0 }; char *blank "  "; main(argc, argv) char *argv[]; { register mf, i; char *cp; int iter; double f1, f2, f3, f4; long t; nlist("/unix", nl); if(nl[0].type == -1) { printf("dk_busy not found in /unix namelist\n"); exit(1); } if(nl[IRF].type > 0){ device[0] = "RF"; xf[0] = 16.0; } if(nl[IRP].type > 0){ device[2] = "RP"; xf[2] = 7.5; } if(nl[IRK].type > 0){ device[1] = "RK"; xf[1] = 11.1; } if(nl[IHP].type > 0){ device[2] = "HP"; xf[2] = 2.5; } if(nl[IHS].type > 0){ device[0] = "HS"; xf[0] = 4.0; } mf = open("/dev/mem", 0); if(mf < 0) { printf("cannot open /dev/mem\n"); exit(1); } iter = 0; if (argc>1&&argv[1][0]=='-') { if (argv[1][1]=='s') sflg++; else if (argv[1][1]=='a') aflg++; else if (argv[1][1]=='t') tflg++; else if (argv[1][1]=='i') iflg++; argc--; argv++; } if(argc > 2) iter = atoi(argv[2]); if (!(sflg|iflg)) { if(tflg) printf(" TTY"); printf("%9.9s",blank); for(i=0;i<3;i++){ if(device[i] == 0) continue; printf("%s%16.16s",device[i],blank); } printf("PERCENT\n"); if(tflg) printf(" tin tout"); for(i=0;i<3;i++){ if(device[i] == 0) continue; printf(" tpm msps mspt"); } printf(" user nice systm idle\n"); } loop: seek(mf, nl[0].value, 0); read(mf, &s, sizeof s); for(i=0; i<40; i++) { t = s.etime[i]; s.etime[i] =- s1.etime[i]; s1.etime[i] = t; } t = 0; for(i=0; i<32; i++) t =+ s.etime[i]; etime = t; if(etime == 0.) etime = 1.; if (aflg) printf("%.2f minutes total\n", etime/3600); if (sflg) { stats2(etime); goto contin; } if (iflg) { stats3(etime); goto contin; } etime =/ 60.; if(tflg) { f1 = s.tin; f2 = s.tout; printf("%6.1f", f1/etime); printf("%6.1f", f2/etime); } for(i=0; i<3; i++){ if(device[i] == 0) continue; stats(i); } for(i=0; i<4; i++){ stat1(i*8); } printf("\n"); contin: --iter; if(iter) if(argc > 1) { sleep(atoi(argv[1])); goto loop; } } stats(dn) { register i; double f1, f2, f3; double f4, f5, f6; long t; t = 0; for(i=0; i<32; i++) if(i & (1< 1) { if (**argv<'0' || **argv>'9') goto usage; res = kill(pid = atoi(*argv), signo); if (res<0) { printf("%u: %s\n", pid, sys_errlist[errno]); errlev = 1; } argc--; argv++; } return(errlev); } ster signo, pid, res; int errlev; extern char *sys_errlist[]; extern errno; errlev = 0; if (argc <= 1) { usage: printf("usage: kill [ -signo ] pid ...\n"); exit(2); } if (*argv[1] == '-') { signo = atoi(argv[1]+1); argc--; argv++; } else signo = 15; argv++; while (argc > 1) { if (**argv<'0' || **argv>'9') goto usage; res = kill(pid = atoi(*argv), signo); if (res<0) { printf("%u: %s\n", pid, sys_#define SIGHUP 1 #define SIGINT 2 #define SIGQIT 3 #define SIGCLK 14 #define SIGTRM 15 #define SU 0 #define MSGSZ 106 #define NOACK 64 struct minfo { int mpid; int mtype; } minfo; int mtext[MSGSZ]; int getsig(); int stop; int efno; char *errfile "/usr/adm/errfile"; main(argc,argv) char **argv; { register int n; int fil[2]; signal(SIGHUP,1); signal(SIGINT,1); signal(SIGQIT,1); if(argc > 1) errfile = *++argv; if(pipe(fil) < 0) error("Can't pipe"); if((n = fork()) > 0) { close(fil[1]); while((n = read(fil[0],mtext,sizeof(mtext))) > 0) write(1,mtext,n); exit(0); } else if(n < 0) { error("Can't fork"); } /* Error Log Daemon */ close(fil[0]); close(0); open("/",0); /* guarantee fd 0 in use */ close(1); dup(fil[1]); close(fil[1]); setuid(SU); if(getuid()&0377) error("Not super-user"); signal(SIGTRM,&getsig); if((efno = open(errfile,1)) < 0) if((efno = creat(errfile,0666)) < 0) error("Can't open/create %s",errfile); seek(efno,0,2); if(msgenab() < 0) error("Can't enable messages"); if(errlog(1) < 0) error("Can't start logging"); for(n = 0; n < 20; n++) if(n != efno) close(n); while(!stop) { if((n = recvw(mtext,sizeof(mtext),&minfo,0)) > 0) wrtmsg(n); } errlog(0); while((n = recv(mtext,sizeof(mtext),&minfo,0)) > 0) wrtmsg(n); exit(0); } wrtmsg(n) { if(minfo.mpid == 0 && minfo.mtype == NOACK) { write(efno,mtext,n); } } getsig(n) { signal(n, &getsig); if(n == SIGTRM) stop++; } error(s1,s2) { printf(s1,s2); putchar('\n'); exit(16); } n't enable messages"); if(errlog(1) < 0) error("Can't start logging"); for(n = 0; n < 20; n++) if(n != efno) close(n); while(!stop) { if((n = recvw(mtext,sizeof(mtext),&minfo,0)) > 0) wrtmsg(n); } errlog(0); while((n = recv(mtext,sizeof(mtext),&minfo,0)) > 0) wrtmsg(n); exit(0); } wrtmsg(n) { if(minfo.mpid == 0 && minfo.mtype == NOACK) { write(efno,mtext,n); } } getsig(n) { signal(n, &getsig); if(n == SIGTRM) stop++; } error(s1,s2) { printf(s1,s2); putchar('\n'); exit(16# /* Format and interpret the error log file */ #define araysz(x) ((sizeof(x)/sizeof(x[0]))-1) #define PAD 9 #define NSP 8 #define NF 0 #define MAXLEN 65 #define PGLEN 60 /* space allowances for report sections */ #define SNEED 10 #define TNEED 7 #define DNEED 5 #define ANEED 12 #define BNEED 5 #define CNEED 6 #define ONE 1 /* true major device numbers */ #define RK 0 #define RP 1 #define RF 2 #define TM 3 #define TC 4 #define HP 5 #define HT 6 #define HS 7 /* error record header */ struct emsghd { char e_type; char e_fill; long e_ctime; } emsghd; /* startup record */ struct estart { int es_cpu; int es_mmr3; char es_nbdev; char es_ncdev; int es_bconf; int es_cconf; }estart; /* time change record */ struct etchg { long e_ntime; } etchg; struct iostat { long io_ops; long io_misc; int io_unlog; }; /* block device error record */ struct eblock { char d_minor; char d_major; struct iostat e_stat; int e_bacty; int e_cacty; char e_rtry; char e_nreg; int e_rloc; int eb_bflg; int eb_wcnt; long eb_maddr; int eb_bno; } eblock; /* RP03 minor device starting cylinder numbers */ int rpoffst[] { 0, 203, 0, 360, 0, 78, 0, 328 }; /* RP04 minor device starting cylinder numbers */ int hpoffst[] { 0, 44, 201, 358, 0, 100, 201, 300, 0, 44, 202, 360, 408, 566, 724, 44, 123, 202, 281, 380, 408, 487, 566, 645, 0, 0, 0, 0, 0, 0, 0, 0 }; int col; int file; int tab[6] {0,8,16,40,51,5}; int drvregs[30]; char *cbuf; char *htime[20]; char *header "UNIX SYSTEM ERROR REPORT"; char *hd1 "UNIX System Error Report - Selected Items"; char *hd2 "UNIX Summary Error Report"; struct inode { int dev; int inum; int flags; char nlink; char uid; char gid; char size0; int size; int ptr[8]; int atime[2]; int mtime[2]; }; char *dev[] { "RK05", "RP03", "RF11", "TU10", "TC11", "RP04/5", "TU16", "RS03/4", 0 }; char *rkregs[] { "RKDS", "RKER", "RKCS", "RKWC", "RKBA", "RKDA", "RKDB", 0 }; char *rpregs[] { "RPDS", "RPER", "RPCS", "RPWC", "RPBA", "RPCA", "RPDA", "RPM1", "RPM2", "RPM3", "SUCA", 0 }; char*rfregs[] { "RFCS", "RFWC", "RFBA", "RFDA", "RFDAE", "RFDB", "RFMA", "RFADS", 0 }; char *tmregs [] { "TMER", "TMCS", "TMBC", "TMBA", "TMDB", "TMRD", 0 }; char *tcregs [] { "TCCSR", "TCCM", "TCWC", "TCBA", "TCDT", 0 }; char *hpregs[] { "HPCS1", "HPWC", "HPBA", "HPDA", "HPCS2", "HPDS", "HPER1", "HPAS", "HPLA", "HPDB", "HPMR", "HPDT", "HPSN", "HPOF", "HPDC", "HPCC", "HPER2", "HPER3", "HPEC1", "HPEC2", "HPBAE", "HPCS3", 0 }; char *htregs [] { "HTCS1", "HTWC", "HTBA", "HTFC", "HTCS2", "HTDS", "HTER", "HTAS", "HTCK", "HTDB", "HTMR", "HTDT", "HTSN", "HTTC", "HTBAE", "HTCS3", 0 }; char *hsregs[] { "HSCS1", "HSWC", "HSBA", "HSDA", "HSCS2", "HSDS", "HSER", "HSAS", "HSLA", "HSDB", "HSMR", "HSDT", "HSBAE", "HSCS3", 0 }; int rkblk(); int rpblk(); int rfblk(); int tmblk(); int tcblk(); int hpblk(); int htblk(); int hsblk(); /* Device specification functions */ /* Must remain in same order as true major device numbers */ int (*func[]) () { &rkblk, &rpblk, &rfblk, &tmblk, &tcblk, &hpblk, &htblk, &hsblk, 0 }; int devregs[] { &rkregs, &rpregs, &rfregs, &tmregs, &tcregs, &hpregs, &htregs, &hsregs, 0 }; char *ediag [] { "First Error", "First Retry", "Logging Terminated", 0 }; struct pos { int flg; int unit; int cyl; int trk; int sector; } pos; char *msg[] { "User D Space Enabled", "Supervisor D Space Enabled", "Kernel D Space Enabled", "", "22 bit mapping Enabled", "UNIBUS MAP relocation Enabled", 0 }; char *label[] { "ERROR logged at", "Physical Device", "Logical Device", "Device Address", "Retry Count", "Error Diagnosis", "Registers at Error time", "Physical Buffer Start Address", "Transfer Size in Bytes", "Cylinder Requested", "Track Requested", "Sector Requested", "Type of Transfer", "Block No. in Logical File System", "Statistics on Device", "No. of R/W Operations to date", "No. of Other Operations", "No. of Unrecorded Errors", "Simultaneous Bus Activity", "I/O Type", 0 }; int page 1; int line; int n 0; int xflg; int yflg; int fout; main (argc,argv) char *argv[]; int argc; { int i; char c; argc--; argv++; while (argc>1&&(**argv)=='-') { for (;(**argv);*++*argv) switch (**argv) { case 'x': xflg++; header = hd1; printf("Currently not implemented\n"); break; case 'y': yflg++; header = hd2; printf("Currently not implemented\n"); break; default: printf("%c?\n",**argv);  } } fout = dup (1); if (argc ==0) report("/usr/adm/errfile"); else while(argc--) report(*argv++); flush (); exit(0); } report(fp) char *fp; { if((file = open(fp,0))<0) { printf("Cannot open %s\n",fp); return; } inithdng(); puthead(header); putdata(); putft(); close (file); return; } putdata() { int m; while(m=read(file,&emsghd,sizeof(emsghd)) ==sizeof(emsghd)) { switch(emsghd.e_type) { case 010: getstart(); break; case 011: getdown(); break; case 012: getime(); break; case 020: case 021: case 022: getblk(); break; case 060: printf("CPU error\n"); line++; break; case 040: printf("Character device error\n"); line++; break; default: printf("Unrecognizable data\n"); line++; flush(); exit(8); } } return; } getdown() { need(DNEED); printf("\nERROR LOGGING SYSTEM SHUTDOWN - %s\n\n\n", ctime(&emsghd.e_ctime)); } getime() { int p; need(TNEED); printf("\n\n ********** TIME CHANGE ***** FROM %s",  ctime(&emsghd.e_ctime)); if(p=read(file,&etchg,sizeof(etchg))!=sizeof(etchg)) { need(ONE); printf("Time change record read error\n"); return; } printf("\t\t\t\t TO %s \n\n\n\n",ctime(&etchg.e_ntime)); } getblk() { register int i,j; register char **p; pos.flg = 0; if(j=read(file,&eblock,sizeof(eblock))!=sizeof(eblock)) { need(ONE); printf("Block device entry record error\n"); return; } if(eblock.d_major > araysz(func)) return; (*func[eblock.d_major])(); col=0; need(ANEED); format(NSP,tab[1],"\n",tab[1],dev[eblock.d_major]); format(NF,tab[5],label[0],tab[3],"%s",ctime(&emsghd.e_ctime)); format(NF,tab[1],label[1],tab[3],"%d",pos.unit); format(NF,tab[1],label[2],tab[3],"%d",eblock.d_minor); format(NF,tab[1],label[3],tab[3],"%o",eblock.e_rloc); printf("\n"); format(NF,tab[1],label[4],tab[3],"%d",eblock.e_rtry); format(NF,tab[1],label[5],tab[3],"%s",ediag[emsghd.e_type&07]); format(NSP,tab[1],label[18],tab[3],"%s",""); if(eblock.e_bacty == 0) printf("%s","None"); else for(i=0;i=0;i--) { if(estart.es_mmr3 & (1<>3); pos.cyl=rpoffst[eblock.d_minor&07]; pos.cyl =+ ldiv(0,eblock.eb_bno,10*20); pos.trk = ldiv(0,ldivr,10); pos.sector = ldivr; } rfblk() { extern ldivr; pos.flg=1; pos.unit=ldiv(0,eblock.eb_bno,1024); pos.cyl=ldiv(0,ldivr,8); pos.trk=0; pos.sector=ldivr; } tmblk() { pos.unit = (eblock.d_minor&03); } tcblk() { pos.unit = (eblock.d_minor&07); } hpblk() { extern ldivr; pos.flg = 1; pos.unit=(eblock.d_minor>>5)&0377; pos.cyl = hpoffst[eblock.d_minor&037]; pos.cyl =+ ldiv(0,eblock.eb_bno,19*22); pos.trk = ldiv(0,ldivr,22); pos.sector=ldivr; } htblk() { pos.unit=(eblock.d_minor&03); } hsblk() { extern ldivr; pos.flg = 1; pos.trk=0; pos.unit=eblock.d_minor&07; pos.cyl = ldiv(0,eblock.eb_bno,eblock.d_minor&010?32:16); pos.sector = ldivr; } nextcol(nextab) /* position to next tab */ int nextab; { int i,df; df = (nextab>>3) - (col>>3); if(df<0) { df = (nextab>>3); col = 0; } for(i=0;i= MAXLEN) { page++; puthead(header); return; } putft(); puthead(header); return; } need(a) /* acts like ".ne" command of nroff */ int a; { if( line>(PGLEN-a)) trnpg(); line =+ a; return; } pad(nm) /* fill out an address with zeros */ int nm; { int i; if((i=(nm>>3))&&(n<6)) { n++; pad(i); } for(;n<5;n++) putchar('0'); return; } strcpy(a,b) /* copy a string */ char *a,*b; { while(*b++ = *a++); } le (line<=MAXLEN) { putchar('\n'); line++; } page++; } trnpg() { if( line >= MAXLEN) { page++; puthead(heade# /* * ln target [ new name ] */ struct ibuf { int inum; int iflags; char inl; char iuid; int isize; int iaddr[8]; char *ictime[2]; char *imtime[2]; int fill; }; #define DIR 040000 #define FMT 060000 main(argc, argv) char **argv; { static struct ibuf statb; register char *np; if (argc<2) { write(1, "Usage: ln target [ newname ]\n", 29); exit(1); } if (argc==2) { np = argv[1]; while(*np++); while (*--np!='/' && np>argv[1]); np++; argv[2] = np; } stat(argv[1], &statb); if ((statb.iflags&FMT) == DIR) { write(1, "No directory link\n", 18); exit(1); } if (link(argv[1], argv[2])<0) { write(1, "Can't link\n", 11); exit(1); } exit(0); } #define DIR 040000 #define FMT 060000 main(argc, argv) char **argv; { static struct ibuf statb; register char *np; if (argc<2) { write(1, "Usage: ln target [ newname ]\n", 29); exit(1); } if (argc==2) { np = argv[1]; while(*np++); while (*--np!='/' && np>argv[1]); np++; argv[2] = np; } stat(argv[1], &statb); if # /* * login [ name ] */ struct utmp { char name[8]; int line; int time[2]; int pid; } utmp; struct { int regs[2]; int tflags; } ttyb; struct { int junk[5]; int size; int more[12]; } statb; int cbuf[256]; char *ttyx; char zero[16]; char *utmpf "/etc/utmp"; char *wtmpf "/etc/wtmp"; int lid; #define ECHO 010 main(argc, argv) char **argv; { register struct utmp *p; register char *namep,*np; char pbuf[128]; char pwbuf[9]; int f, c, uid; struct{ char lobyte; char hibyte; }; signal(3, 1); signal(2, 1); ttyx = "/dev/ln\0\0"; lid = lnxx(0); if(lid.lobyte == 'x' && lid.hibyte == 'x'){ write(1, "Sorry.\n", 7); exit(-1); } ttyx[7] = lid.lobyte; ttyx[8] = lid.hibyte; loop: namep = utmp.name; if (argc>1) { np = argv[1]; while (namep= 0) { while(read(f, &c, 1) > 0) write(1, &c, 1); close(f); } if (stat(".mail", &statb) >= 0 && statb.size) write(1, "You have mail.\n", 15); chown(ttyx, uid); setgid(1); setuid(uid); if (*np == '\0') np = "/bin/sh"; execl(np, "-", 0); write(1, "No shell.\n", 9); exit(-1); bad: write(1, "Login incorrect.\n", 17); goto loop; } getpwentry(name, buf) char *name, *buf; { extern fin; int fi, r, c; register char *gnp, *rnp; fi = fin; r = 1; if((fin = open("/etc/passwd", 0)) < 0) goto ret; loop: gnp = name; rnp = buf; while((c=getchar()) != '\n') { if(c == '\0') goto ret; *rnp++ = c; } *rnp++ = '\0'; rnp = buf; while (*gnp++ == *rnp++); if ((*--gnp!=' ' && gnp 0) { for(p = &cbuf; (k =- 16) >= 0; p++){ if(p->line != lid) continue; utmp.name[0] =| 0200; /*line process*/ utmp.line = p->line; time(utmp.time); utmp.pid = p->pid; seek(rw,-(k+16),1); /*relative offset from end*/ write(rw,&utmp,16); close(rw); if ((rw = open(wtmpf, 1)) >= 0) { seek(rw, 0, 2); write(rw, &utmp, 16); close(rw); } return; } } } g() { register struct utmp *p; register rw,k; if((rw=open(utmpf,2))/ lpd -- Line Printer daemon .globl fopen, getc .globl fcreat, putc, flush .globl switch sys signal; 1; 1 sys signal; 2; 1 sys signal; 3; 1 / ignore quit,intr,hup sys stat; lock; buf bec 2f sys creat; lock; 0 bes 2f sys open; lpd; 0 bes 3f mov r0,r1 1: mov r1,r0 sys read; dbuf; 16. bes 3f tst r0 beq 3f tst dbuf beq 1b cmp dbuf+2,$"df bne 1b sys fork br retry sys exit 3: sys unlink; lock 2: sys exit / get line printer retry: jsr r5,aclose mov $lpr,r0 jsr r5,fcreat; print bes error sys chdir; lpd bes error sys open; lpd; 0 bes error mov r0,dfi br loop done: sys unlink; lock sys exit error: jsr r5,aclose mov $10.,r0 sys sleep sys stat; lock; buf bes done / die if lock is gone br retry / look in directory for work loop: mov dfi,r0 sys seek; 0; 0 1: mov dfi,r0 sys read; dbuf; 16. bes error tst r0 beq done / only non-error return tst dbuf beq 1b mov $dbuf+2,r0 cmp (r0),$"df / look for daemon file bne 1b / found prototype file jsr r5,fopen; proto bes 1b / copy a line into buf / only work is expansion of tabs loop1: mov $buf,r1 1: jsr r5,getc; proto bes eloop1 movb r0,(r1) cmp r0,$'\t beq 2f cmpb (r1)+,$'\n bne 1b br 1f 2: movb $' ,(r1)+ cmp r1,$buf+8. beq 1b cmp r1,$buf+16. bhis 1b br 2b 1: movb buf,r0 jsr r5,switch; sptab / done with a prototype file / look for U's in second pass eloop1: mov proto,r0 sys seek; 0; 0 br 2f 1: jsr r5,getc; proto bes 1f 3: cmp r0,$'\n bne 1b 2: jsr r5,getc; proto bes 1f cmp r0,$'U bne 3b mov $buf,r1 3: jsr r5,getc; proto bes 1f movb r0,(r1)+ cmp r0,$'\n bne 3b clrb -(r1) sys unlink; buf br 2b 1: mov proto,r0 sys close sys unlink; dbuf+2 br loop / list of special characters / switchout sptab: 'L; literal 'B; binary 'F; form 'U; loop1 / unlink on second pass 0; 0 literal: jmp loop1 form: clrb -(r1) mov $buf+1,r0 jsr r5,fopen; insert bes loop1 mov $14,r0 jsr r5,putc; print br 1f binary: clrb -(r1) mov $buf+1,r0 jsr r5,fopen; insert bes loop1 1: jsr r5,getc; insert bes 1f jsr r5,putc; print br 1b 1: jsr r5,flush; print mov insert,r0 sys close br loop1 aclose: mov $9.,r1 1: mov r1,r0 sys close dec r1 bge 1b rts r5 lpr: lock: lpd: .even .bss ch: .=.+2 dfi: .=.+2 click: .=.+2 tim: .=.+2 dbuf: .=.+18. print: .=.+518. proto: .=.+518. insert: .=.+518. buf: .=.+400. sleep = 35. signal = 48. r0 jsr r5,putc; print br 1f binary: clrb -(r1) mov $buf+1,r0 jsr r5,fopen; insert bes loop1 1: jsr r5,getc/* * lpr -- on line print to Line Printer */ tfname; nact; tff; first; main(argc, argv) int argc; char *argv[]; { char *arg, *remote; int c, f, flag, cflag; flag = 0; tfname = ranname("/usr/lpd/tfxxx"); if(tfname) tff = creat(tfname, 0666); else tff = -1; if(tff < 0) { printf("Cannot create in /usr/lpd\n"); exit(); } ident(); if(argc == 1) copy(0); while(--argc) { arg = *++argv; c = *arg; if(c == '+' || c == '-') { cflag = c; if(*++arg == '\0') { flag = cflag; continue; } } else cflag = flag; if(cflag == '+') goto cf; if(*arg == '/' && cflag != '-') { card('F', arg); nact++; continue; } f = ranname("/usr/lpd/lfxxx"); if(f) { if(link(arg, f)) goto cf; card('F', f); card('U', f); nact++; goto df; } cf: f = open(arg, 0); if(f < 0) { printf("Cannot open %s\n", arg); continue; } copy(f); close(f); df: if(cflag == '-') { f = unlink(arg); if(f < 0) printf("Cannot remove %s\n", arg); } }  if(nact) { f = ranname("/usr/lpd/dfxxx"); if(f) link(tfname, f); else printf("Cannot rename in /usr/lpd\n"); unlink(tfname); execl("/etc/lpd", "lpd", 0); } unlink(tfname); } copy(f) int f; { int fn, ff, i, nr, nc; static int buf[256]; fn = ranname("/usr/lpd/cfxxx"); if(fn) ff = creat(fn, 0666); else ff = -1; if(ff < 0) { printf("Cannot create in /usr/lpd\n"); return; } nc = 0; nr = 0; while((i = read(f, buf, 512)) > 0) { write(ff, buf, i); nc =+ i; if(nc >= 512) {  nc =- 512; nr++; if(nr > 400) { printf("Copy file is too large\n"); break; } } } close(ff); card('F', fn); card('U', fn); nact++; } card(c, s) int c; char s[]; { char *p1, *p2; static char buf[512]; int col; p1 = buf; p2 = s; col = 0; *p1++ = c; while((c = *p2++) != '\0') { *p1++ = c; col++; } *p1++ = '\n'; write(tff, buf, col+2); } ident() { int c, i, j, n; char *b1p; static char b1[100], b2[100]; b1p = b1; if(getpw(getuid(), b1)) { b1p = "pdp:::m0130,m322:"; } j = 0; while(c = "$ ident "[j]) b2[j++] = c; i = 0; n = 4; while(--n) while(b1p[i++] != ':'); while((c = b1p[i++]) != ':') b2[j++] = c; b2[j++] = ','; i = 0; while((c = b1p[i++]) != ':') b2[j++] = c; b2[j++] = '\0'; card('L', b2); } ranname(s) char s[]; { static int buf[20]; loop: s[11] = ranc(); s[12] = ranc(); s[13] = ranc(); if(stat(s, buf)) return(s); goto loop; } ranc() { int buf[2], c; if(!first) { time(buf); srand(buf[1]); first++; } c = rand(); return(((c>>11)%10)+'0'); } e(c = "$ ident "[j]) b2[j++] = c; i = 0; n = 4; while(--n) while(b1p[i++] != ':'); while((c = b1p[i++]) != ':') b2[j++] = c; b2[j++] = ','; i = 0; while((c = b1p[i++]) != ':') b2[j++] = c; b2[j++] = '\0'; card('L', b2); } ranname(s) char s[]; { static int buf[20]; loop: s[11] = ranc(); s[12] = ranc(); s[13] = ranc(); if(stat(s, buf)) return(s); goto loop; } ranc() { int buf[2], c; if(!first) { time(buf); srand(buf[1]); first++; } c = rand(); return(# /* * list file or directory */ struct { int fdes; int nleft; char *nextc; char buff[512]; } inf; struct ibuf { int idev; int inum; int iflags; char inl; char iuid; char igid; char isize0; int isize; int iaddr[8]; char *iatime[2]; char *imtime[2]; }; struct lbuf { char lname[14]; int lnum; int lflags; char lnl; char luid; char lgid; char lsize0; int lsize; char *lmtime[2]; }; struct lbufx { char *namep; }; int aflg, dflg, lflg, sflg, tflg, uflg, iflg, fflg; int fout; int rflg 1; int flags; int uidfil -1; int tblocks; int statreq; struct lbuf *lastp &end; struct lbuf *rlastp &end; char *dotp "."; #define IFMT 060000 #define DIR 0100000 #define CHR 020000 #define BLK 040000 #define ISARG 01000 #define LARGE 010000 #define SUID 04000 #define SGID 02000 #define ROWN 0400 #define WOWN 0200 #define XOWN 0100 #define RGRP 040 #define WGRP 020 #define XGRP 010 #define ROTH 04 #define WOTH 02 #define XOTH 01 main(argc, argv) char **argv; { int i, j; extern end; register struct lbuf *ep, *ep1; register struct lbuf *slastp; struct lbuf lb; int compar(); fout = dup(1); if (--argc > 0 && *argv[1] == '-') { argv++; while (*++*argv) switch (**argv) { case 'a': aflg++; continue; case 's': sflg++; statreq++; continue; case 'd': dflg++; continue; case 'l': lflg++; statreq++; uidfil = open("/etc/passwd", 0); continue; case 'r': rflg = -1; continue; case 't': tflg++; statreq++; continue; case 'u': uflg++; continue; case 'i': iflg++; continue; case 'f': fflg++; continue; default: continue; } argc--; } if (fflg) { aflg++; lflg = 0; sflg = 0; tflg = 0; statreq = 0; } if (argc==0) { argc++; argv = &dotp - 1; } for (i=0; i < argc; i++) { if ((ep = gstat(*++argv, 1))==0) continue; ep->namep = *argv; ep->lflags =| ISARG; } qsort(&end, lastp - &end, 28, compar); slastp = lastp; for (ep = &end; eplflags&DIR && dflg==0 || fflg) { if (argc>1) printf("\n%s:\n", ep->namep); lastp = slastp; readdir(ep->namep); if (fflg==0) qsort(slastp, lastp - slastp, 28, compar); if (statreq) printf("total %d\n", tblocks); for (ep1=slastp; ep1lnum == -1) return; if (iflg) printf("%5d ", p->lnum); if (lflg) { pmode(p->lflags);  printf("%2d ", p->lnl); if (getname(p->luid&0377, tbuf)==0) printf("%-6.6s", tbuf); else printf("%-6d", p->luid&0377); if (p->lflags & (BLK|CHR)) printf("%3d,%3d", p->lsize.dmajor&0377, p->lsize.dminor&0377); else printf("%7s", locv(p->lsize0, p->lsize)); printf(" %-12.12s ", ctime(p->lmtime)+4); } else if (sflg) printf("%4d ", nblock(p->lsize0, p->lsize)); if (p->lflags&ISARG) printf("%s\n", p->namep); else printf("%.14s\n", p->lname); } getname(uid, buf) int uid; char buf[]; { int j, c, n, i; inf.fdes = uidfil; seek(inf.fdes, 0, 0); inf.nleft = 0; do { i = 0; j = 0; n = 0; while((c=getc(&inf)) != '\n') { if (c<0) return(-1); if (c==':') { j++; c = '0'; } if (j==0) buf[i++] = c; if (j==2) n = n*10 + c - '0'; } } while (n != uid); buf[i++] = '\0'; return(0); } nblock(size0, size) char *size0, *size; { register int n; n = ldiv(size0, size, 512); if (size&0777) n++; if (n>8) n =+ (n+255)/256; return(n); } int m0[] { 3, DIR, 'd', BLK, 'b', CHR, 'c', '-'}; int m1[] { 1, ROWN, 'r', '-' }; int m2[] { 1, WOWN, 'w', '-' }; int m3[] { 2, SUID, 's', XOWN, 'x', '-' }; int m4[] { 1, RGRP, 'r', '-' }; int m5[] { 1, WGRP, 'w', '-' }; int m6[] { 2, SGID, 's', XGRP, 'x', '-' }; int m7[] { 1, ROTH, 'r', '-' }; int m8[] { 1, WOTH, 'w', '-' }; int m9[] { 1, XOTH, 'x', '-' }; int *m[] { m0, m1, m2, m3, m4, m5, m6, m7, m8, m9}; pmode(aflag) { register int **mp; flags = aflag; for (mp = &m[0]; mp < &m[10];) select(*mp++); } select(pairp) int *pairp; { register int n, *ap; ap = pairp; n = *ap++; while (--n>=0 && (flags&*ap++)==0) *ap++; putchar(*ap); } makename(dir, file) char *dir, *file; { static char dfile[100]; register char *dp, *fp; register int i; dp = dfile; fp = dir; while (*fp) *dp++ = *fp++; *dp++ = '/'; fp = file; for (i=0; i<14; i++) *dp++ = *fp++; *dp = 0; return(dfile); } readdir(dir) char *dir; { static struct { int dinode; char dname[14]; } dentry; register char *p; register int j; register struct lbuf *ep; if (fopen(dir, &inf) < 0) { printf("%s unreadable\n", dir); return; } tblocks = 0; for(;;) { p = &dentry; for (j=0; j<16; j++) *p++ = getc(&inf); if (dentry.dinode==0 || aflg==0 && dentry.dname[0]=='.') continue; if (dentry.dinode == -1) break; ep = gstat(makename(dir, dentry.dname), 0); if (ep->lnum != -1) ep->lnum = dentry.dinode; for (j=0; j<14; j++) ep->lname[j] = dentry.dname[j]; } close(inf.fdes); } gstat(file, argfl) char *file; { struct ibuf statb; register struct lbuf *rep; if (lastp+1 >= rlastp) { sbrk(512); rlastp.idev =+ 512; } rep = lastp; lastp++; rep->lflags = 0; rep->lnum = 0; if (argfl || statreq) { if (stat(file, &statb)<0) { printf("%s not found\n", file); statb.inum = -1; statb.isize0 = 0; statb.isize = 0; statb.iflags = 0; if (argfl) { lastp--; return(0); } } rep->lnum = statb.inum; statb.iflags =& ~(ISARG | DIR); if ((statb.iflags&IFMT) == 060000) { statb.iflags =& ~020000; } else if ((statb.iflags&IFMT)==040000) { statb.iflags =& ~IFMT; statb.iflags =| DIR; } rep->lflags = statb.iflags; rep->luid = statb.iuid; rep->lgid = statb.igid; rep->lnl = statb.inl; rep->lsize0 = statb.isize0; rep->lsize = statb.isize; if (rep->lflags & (BLK|CHR) && lflg) rep->lsize = statb.iaddr[0]; rep->lmtime[0] = statb.imtime[0]; rep->lmtime[1] = statb.imtime[1]; if(uflg) { rep->lmtime[0] = statb.iatime[0]; rep->lmtime[1] = statb.iatime[1]; } tblocks =+ nblock(statb.isize0, statb.isize); } return(rep); } compar(ap1, ap2) struct lbuf *ap1, *ap2; { register struct lbuf *p1, *p2; register int i; int j; struct { char *charp;}; p1 = ap1; p2 = ap2; if (dflg==0) { if ((p1->lflags&(DIR|ISARG)) == (DIR|ISARG)) { if ((p2->lflags&(DIR|ISARG)) != (DIR|ISARG)) return(1); } else { if ((p2->lflags&(DIR|ISARG)) == (DIR|ISARG)) return(-1); } } if (tflg) { i = 0; if (p2->lmtime[0] > p1->lmtime[0]) i++; else if (p2->lmtime[0] < p1->lmtime[0]) i--; else if (p2->lmtime[1] > p1->lmtime[1]) i++; else if (p2->lmtime[1] < p1->lmtime[1]) i--; return(i*rflg); } if (p1->lflags&ISARG) p1 = p1->namep; else p1 = p1->lname; if (p2->lflags&ISARG) p2 = p2->namep; else p2 = p2->lname; for (i=0; i<14; i++) if ((j = *p1.charp++ - *p2.charp++) || p1.charp[-1]==0) return(rflg*j); return(0); } ISARG)) return(-1); } } if (tflg) { i = 0; if (p2->lmtime[0] > p1->lmtime[0]) i++; else if (p# /* mail command usage mail prints your mail mail people sends standard input to people */ #define SIGINT 2 /* Overall status */ #define ALLGOOD 0 #define SOMEBAD 4 #define ALLBAD -1 /* Incremental status */ #define GOOD 0 #define BAD 4 #define VBAD -1 struct xcode{ int summary; int count; }xcode; struct utmp { char name[8]; char tty1; char tty2; int ltime[2]; int pad2; }ubuf; struct passwd { char *pw_name; char *pw_passwd; int pw_uid; char *pw_gecos; char *pw_dir; char *pw_shell; }; char lettmp[] "/tmp/maxxxxx"; char preptmp[] "/tmp/mbxxxxx"; char *utmpf "/etc/utmp"; int pwfil; struct{ char lobyte; char hibyte; }; main(argc, argv) char **argv; { int me,uf; extern fout; register struct passwd *p; register char *cp; xcode.summary = ALLGOOD; xcode.count = argc; maketemp(); if (argv[1][0]=='-') xcode.count--; if (argc==1 || argc==2 && argv[1][0]=='-') { printmail(argc, argv); delexit(); } signal(SIGINT, delexit); xcode.count--; fout = creat(lettmp, 0600); me = lnxx(1); if(me.lobyte == 'x' && me.hibyte == 'x'){ me = lnxx(2); if(me.lobyte == 'x' && me.hibyte == 'x') goto out; } if((uf=open(utmpf,0)) > 0) { while (read(uf, &ubuf, sizeof ubuf) == sizeof ubuf) if((ubuf.tty1 == me.lobyte)&&(ubuf.tty2 == me.hibyte)){ ubuf.name[0] =& ~0200; /*strip negative*/ ubuf.name[8] = ' '; close(uf); for(cp=ubuf.name; *cp != ' '; cp++); *cp = 0; bulkmail(argc, argv, ubuf.name); } } out: me = getuid() & 0377; setpw(); for (;;) if ((p = getpwent()) && p->pw_uid == me) bulkmail(argc, argv, p->pw_name); fout = 1; printf("Who are you?\n"); xcode.summary = ALLBAD; delexit(); } printmail(argc, argv) char **argv; { extern fin, fout; register n, c, f; int ln; if (fopen(".mail", &fin)>=0 && (c = getchar())) { do { putchar(c); } while (c = getchar()); close(fin); c = 'y'; if (argc<2) { ln = lnxx(0); if(ln.lobyte != 'x' || ln.hibyte != 'x'){ printf("Save?"); fin = 0; c = getchar(); } } else c = argv[1][1]; if (c=='y') { prepend(".mail", "mbox"); printf("Saved mail in 'mbox'\n"); } close(creat(".mail")); } else printf("No mail.\n"); } bulkmail(argc, argv, from) char **argv, *from; { extern fin, fout; int tbuf[2]; int ex; register c; fin = 0; (&fin)[1] = 0; time(tbuf); printf("From %s %s", from, ctime(tbuf)); while (c = getchar()) putchar(c); putchar('\n'); flush(); close(fout); while (--argc > 0) { if((ex = sendto(*++argv)) > GOOD) { xcode.count--; if(ex > xcode.summary) { xcode.summary = ex; } } } delexit(); } sendto(person) char *person; { static saved; extern fout; extern fin; register struct passwd *p; int ln; setpw(); while (p = getpwent()) { if (equal(p->pw_name, person)) { if (prepend(lettmp, cat(p->pw_dir, "/.mail"))==0) { return(BAD); break; } return(GOOD); } } fout = 1; flush(); printf("Can't send to %s.\n", person); ln = lnxx(0); if((ln.lobyte != 'x' || ln.hibyte != 'x') && saved == 0){ unlink("dead.letter"); saved++; printf("Letter saved in 'dead.letter'\n"); prepend(lettmp, "dead.letter"); } return(BAD); } prepend(from, to) char *from, *to; { extern int fin, fout; fcreat(preptmp, &fout); fopen(from, &fin); while (putchar(getchar())); close(fin); fopen(to, &fin); while (putchar(getchar())); close(fin); flush(); close(fout); if (fcreat(to, &fout) < 0) { fout = 1; return(0); } fopen(preptmp, &fin); while(putchar(getchar())); flush(); close(fout); close(fin); fout = 1; return(1); } setpw() { extern fin; if (pwfil == 0) { fopen("/etc/passwd", &fin); pwfil = fin; } else fin = pwfil; (&fin)[1] = 0; seek(fin, 0, 0); } getpwent() { register char *p; register c; static struct passwd passwd; static char line[100]; extern fin; p = line; while((c=getchar()) != '\n') { if(c <= 0) return(0); if(p < line+98) *p++ = c; } *p = 0; p = line; passwd.pw_name = p; p = pwskip(p); passwd.pw_passwd = p; p = pwskip(p); passwd.pw_uid = atoi(p); p = pwskip(p); passwd.pw_gecos = p; p = pwskip(p); passwd.pw_dir = p; p = pwskip(p); passwd.pw_shell = p; return(&passwd); } pwskip(ap) char *ap; { register char *p; p = ap; while(*p != ':') { if(*p == 0) return(p); p++; } *p++ = 0; return(p); } delexit() { unlink(lettmp); unlink(preptmp); if(xcode.count == 0) exit(ALLBAD); else exit(xcode.summary); } maketemp() { int i, pid, d; pid = getpid(); for (i=11; i>=7; --i) { d = (pid&07) + '0'; lettmp[i] = d; preptmp[i] = d; pid =>> 3; } } equal(as1, as2) { register char *s1, *s2; s1 = as1; s2 = as2; while (*s1++ == *s2) if (*s2++ == 0) return(1); return(0); } cat(ap1, ap2) char *ap1, *ap2; { register char *p1, *p2; static char fn[32]; p1 = ap1; p2 = fn; while (*p2++ = *p1++); p2--; p1 = ap2; while (*p2++ = *p1++); return(fn); } exit(ALLBAD); else exit(xcode.summary); } maketemp() { int i, pid, d; pid = getpid(); for (i=11; i>=7; --i) { d = (pid&07) + '0'; lettmp[i] = d; preptmp[i] = d; pid =>/* * mesg -- set current tty to accept or * forbid write permission. * * mesg [y] [n] * y allow messages * n forbid messages */ int sbuf[40]; main(argc, argv) char *argv[]; { register char *tty; register ln; tty = "/dev/ln\0\0"; ln = lnxx(1); tty[7] = ln; tty[8] = ln>>8; if(stat(tty, sbuf) < 0) { write(2, "cannot stat\n", 12); exit(1); } if(argc < 2) { if(sbuf[2] & 02) goto no; goto yes; } if(*argv[1] == 'y') goto yes; no: if(chmod(tty, 0600) < 0) goto bad; goto was; yes: if(chmod(tty, 0622) < 0) goto bad; was: if(sbuf[2] & 02) write(2, "was y\n", 6); else write(2, "was n\n", 6); exit(0); bad: write(2, "cannot change mode\n", 19); exit(1); } er char *tty; register ln; tty = "/dev/ln\0\0"; ln = lnxx(1); tty[7] = ln; tty[8] = ln>>8; if(stat(tty, sbuf) < 0) { write(2, "cannot stat\n", 12); exit(1); } if(argc < 2) { if(sbuf[2] & 02) goto no; goto yes; } if(*argv[1] == 'y') goto yes; no: if(chmod(tty, 0600) < 0) goto bad; goto was;/* * mkdir -- make directories */ main(argc, argv) char **argv; { static char dname[128], pname[128]; static nerror; register char *p1, *p2, *p3; while (--argc > 0) { argv++; p1 = argv[0]; p2 = dname; p3 = pname; while (*p2++ = *p3++ = *p1++); p2[-1] = '/'; *p2++ = '.'; *p2 = '\0'; while (p3>pname && *--p3!='/'); if (p3 > pname) *p3 = '\0'; else if (*p3 == '/') p3[1] = '\0'; else { *p3++ = '.'; *p3++ = '\0'; } if (access(pname, 02)) { perror("mkdir"); nerror++; continue; } if (mknod(argv[0], 0140777, 0) < 0) { perror("mkdir"); nerror++; continue; } chown(argv[0], ((getgid()&0377)<<8) + (getuid()&0377)); if(link(argv[0], dname) < 0) { perror("mkdir"); nerror++; unlink(argv[0]); continue; } *p2++ = '.'; *p2 = '\0'; if(link(pname, dname) < 0) { perror("mkdir"); nerror++; *--p2 = '\0'; unlink(dname); unlink(argv[0]); } } return(nerror); } '\0'; } if (access(pname, 02)) { perror("mkdir"); ne# /* * * */ #define NBAD 50 struct { char *s_isize; char *s_fsize; int s_nfree; int s_free[100]; int s_ninode; int s_inode[100]; char s_flock; char s_ilock; char s_fmod; int s_time[2]; } filsys; struct inode { int i_number; int i_mode; char i_nlink; char i_uid; char i_gid; char i_size0; char *i_size1; int i_addr[8]; int i_time[4]; }; /* modes */ #define IALLOC 0100000 #define IFMT 060000 #define IFDIR 040000 #define IFCHR 020000 #define IFBLK 060000 #define ILARG 010000 #define ISUID 04000 #define ISGID 02000 #define IREAD 0400 #define IWRITE 0200 #define IEXEC 0100 int utime[2]; int fin; int fsi; int fso; char *charp; int buf[256]; char string[50]; char *fsys; char *proto; int badblk[NBAD]; int indx,pflag; char *pstring; char *bad "badblocks"; int compar(); main(argc, argv) char **argv; { int f, n; /* * open relevent files */ time(utime); if(argc < 3) { printf("arg count\n"); exit(); } fsys = *++argv; proto = *++argv; argv++; indx = 0; for(argc=- 4; argc> 0 ; argc-- ){ switch((argv++)[0][1]){ case 'b': while((**argv!='-')&&(**argv!='\0')){ argc--; if(indx>=NBAD){ printf("too many badblocks\n"); exit(); } charp = *argv++; badblk[indx++] = getnum(); } } } charp = 0; fso = creat(fsys, 0666); if(fso < 0) { printf("%s: cannot create\n", fsys); exit(); } fsi = open(fsys, 0); if(fsi < 0) { printf("%s: cannot open\n", fsys); exit(); } fin = open(proto, 0); if(fin < 0) { n = 0; for(f=0; proto[f]; f++) { if(proto[f]<'0' || proto[f]>'9') { printf("%s: cannot open\n", proto); exit(); } n = n*10 + proto[f]-'0'; } filsys.s_fsize = n; filsys.s_isize = ldiv(0, n, 43+ldiv(0, n, 1000)); printf("isize = %d\n", filsys.s_isize); charp = "d--777 0 0 $ "; goto f3; } /* * get name of boot load program * and read onto block 0 */ getstr(); f = open(string, 0); if(f < 0) { printf("%s: cannot open init\n", string); goto f2; } read(f, buf, 020); if(buf[0] != 0407) { printf("%s: bad format\n", string); goto f1; } n = buf[1]+buf[2]; if(n > 512) { printf("%s: too big\n", string); goto f1; } read(f, buf, n); wtfs(0, buf); f1: close(f); /* * get total disk size * and inode block size */ f2: filsys.s_fsize = getnum(); filsys.s_isize = getnum(); f3: if(filsys.s_isize > filsys.s_fsize || filsys.s_fsize-filsys.s_isize-2 < filsys.s_isize) { printf("%l/%l: bad ratio\n", filsys.s_fsize, filsys.s_isize); exit(); } getstr(); pstring = string; while((*bad != '\0')&&(*bad++ == *pstring++)); if(*bad == '\0'){ for(;indx=NBAD){ printf("too many badblocks\n"); exit(); } charp = string; badblk[indx] = getnum(); } charp = 0; }else{ pflag++; } qsort(&badblk,indx,2,&compar); limit(&badblk,--indx); free(0); for(n=filsys.s_fsize-1; n!=filsys.s_isize+1; n--) if(n == badblk[indx]){ while(n == badblk[indx])indx--; }else{ free(n); } /* * initialize files */ for(n=0; n<256; n++) buf[n] = 0; for(n=0; n!=filsys.s_isize; n++) wtfs(n+2, buf); cfile(0); /* * write out super block */ for(n=0; n<256; n++) buf[n] = 0; filsys.s_time[0] = utime[0]; filsys.s_time[1] = utime[1]; wtfs(1, &filsys); } cfile(par) struct inode *par; { struct inode in; int db[256], ib[256]; int dbc, ibc; static ino; int i, f, *p1, *p2; /* * get mode, uid and gid */ if(pflag){ pflag = 0; }else{ getstr(); } in.i_mode = IALLOC; in.i_mode =| gmode(string[0], "bcd", IFBLK, IFCHR, IFDIR); in.i_mode =| gmode(string[1], "u", ISUID); in.i_mode =| gmode(string[2], "g", ISGID); for(i=3; i<6; i++) { if(string[i]<'0' || string[i]>'7') { printf("%c/%s: bad digit\n", string[i], string); exit(); } in.i_mode =| (string[i]-'0')<<(15-3*i); } in.i_uid = getnum(); in.i_gid = getnum(); /* * general initialization prior to * switching on format */ ino++; in.i_number = ino; if(ldiv(0, ino, 16) > filsys.s_isize) { printf("too many inodes\n"); exit(); } in.i_nlink = 1; in.i_size0 = 0; in.i_size1 = 0; for(i=0; i<8; i++) in.i_addr[i] = 0; for(i=0; i<256; i++) { db[i] = 0; ib[i] = 0; } if(par == 0) { par = ∈ in.i_nlink--; } dbc = 0; ibc = 0; switch(in.i_mode&IFMT) { case 0: /* * regular file * contents is a file name */ getstr(); f = open(string, 0); if(f < 0) { printf("%s: cannot open\n", string); break; } while((i=read(f, db, 512)) > 0) { addin(&in, i); newblk(&dbc, db, &ibc, ib); } close(f); break; case IFBLK: case IFCHR: /* * special file * content is maj/min types */ in.i_addr[0] = getnum()<<8; in.i_addr[0] =| getnum(); break; case IFDIR: /* * directory * put in extra links * call recursively until * name of "$" found */ par->i_nlink++; entry(par->i_number, "..", &dbc, db, &ibc, ib); in.i_nlink++; entry(in.i_number, ".", &dbc, db, &ibc, ib); in.i_size1 = 32; for(;;) { getstr(); if(string[0]=='$' && string[1]=='\0') break; entry(ino+1, string, &dbc, db, &ibc, ib); addin(&in, 16); cfile(&in); } break; } if(dbc != 0) newblk(&dbc, db, &ibc, ib); if(ibc > 8) { in.i_mode =| ILARG; dbc = alloc(); wtfs(dbc, ib); in.i_addr[0] = dbc; } else for(i=0; i'9') { printf("%s: bad number\n", string); exit(); } n = n*10 + string[i] - '0'; } return(n); } getstr() { int i, c; loop: switch(c=getch()) { case ' ': case '\t': case '\n': goto loop; case '\0': printf("EOF\n"); exit(); case ':': while(getch() != '\n'); goto loop; } i = 0; do { string[i++] = c; c = getch(); } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0'); string[i] = '\0'; } rdfs(bno, bf) { int n; seek(fsi, bno, 3); n = read(fsi, bf, 512); if(n != 512) { printf("read error: %l\n", bno); exit(); } } wtfs(bno, bf) { int n; seek(fso, bno, 3); n = write(fso, bf, 512); if(n != 512) { printf("write error: %l\n", bno); exit(); } } alloc() { int bno, i; filsys.s_nfree--; bno = filsys.s_free[filsys.s_nfree]; filsys.s_free[filsys.s_nfree] = 0; if(bno == 0) { printf("out of free space\n"); exit(); } if(filsys.s_nfree <= 0) { rdfs(bno, buf); filsys.s_nfree = buf[0]; for(i=0; i<100; i++) filsys.s_free[i] = buf[i+1]; } return(bno); } free(bno) { int i; if(filsys.s_nfree >= 100) { buf[0] = filsys.s_nfree; for(i=0; i<100; i++) buf[i+1] = filsys.s_free[i]; wtfs(bno, buf); filsys.s_nfree = 0; } filsys.s_free[filsys.s_nfree] = bno; filsys.s_nfree++; } entry(ino, str, adbc, db, aibc, ib) char *str; int *adbc, *db, *aibc, *ib; { char *s; int i; db[*adbc] = ino; (*adbc)++; s = &db[*adbc]; for(i=0; i<14; i++) { *s++ = *str; if(*str != '\0') str++; } *adbc =+ 7; if(*adbc >= 256) newblk(adbc, db, aibc, ib); } newblk(adbc, db, aibc, ib) int *adbc, *db, *aibc, *ib; { int bno, i; bno = alloc(); wtfs(bno, db); for(i=0; i<256; i++) db[i] = 0; *adbc = 0; ib[*aibc] = bno; (*aibc)++; if(*aibc >= 256) { printf("indirect block full\n"); exit(); } } getch() { if(charp) return(*charp++); return(getchar()); } compar(el1,el2) int *el1,*el2; { if(*el1<*el2)return(-1); if(*el1>*el2)return(1); return(0); } limit(ary,siz) int *ary; { if(siz<=0)return; if(*ary<= filsys.s_isize +1){ printf("badblock specified in ilist - %d\n", *ary); exit(); } if(ary[siz] >= filsys.s_fsize){ printf("badblock specified outside file system - %d", ary[siz]);  exit(); } } addin(ip, sz) register struct inode *ip; { register char *sav; sav = ip->i_size1; ip->i_size1 =+ sz; if(ip->i_size1 < sav) ip->i_size0++; } } compar(el1,el2) int *el1,*el2; { if(*el1<*el2)return(-1); if(*el1>*el2)return(1); return(0); } limit(ary,siz) int *ary; { if(siz<=0)return; if(*ary<= filsys.s_isize +1){ printf("badblock specified in ilist - %d\n", *ary); exit(); } if(ary[siz] >= filsys.s_fsize){ printf("badblock specified outside file system - %d", ary[siz]); main(argc, argv) int argc; char **argv; { int m, a, b; if(argc != 5) { printf("arg count\n"); goto usage; } if(*argv[2] == 'b') m = 0160666; else if(*argv[2] == 'c') m = 0120666; else goto usage; a = number(argv[3]); if(a < 0) goto usage; b = number(argv[4]); if(b < 0) goto usage; if(mknod(argv[1], m, (a<<8)|b) < 0) perror("mknod"); exit(); usage: printf("usage: mknod name b/c major minor\n"); } number(s) char *s; { int n, c; n = 0; while(c = *s++) { if(c<'0' || c>'9')  return(-1); n = n*10 + c-'0'; } return(n); } , b; if(argc != 5) { printf("arg count\n"); goto usage; } if(*argv[2] == 'b') m = 0160666; else if(*argv[2] == 'c') m = 0120666; else goto usage; a = number(argv[3]); if(a < 0) goto usage; b = number(argv[4]); if(b < 0) goto usage; if(mknod(argv[1], m, (a<<8)|b) < 0) perror("mknod"); exit(); usage: printf("usage: mknod name b/c major minor\n"); } number(s) char *s; { int n, c; n = 0; while(c = *s++) { if(c<'0' || c>'9') # /* UNIX MODIFICATION 2.17 */ struct inode { int i_dev; int i_number; int i_mode; char i_nlink; char i_uid; char i_gid; char i_size0; char *i_size1; int i_addr[8]; int i_time[4]; }; /* modes */ #define IALLOC 0100000 #define IFMT 060000 #define IFDIR 040000 #define IFCHR 020000 #define IFBLK 060000 #define ILARG 010000 #define ISUID 04000 #define ISGID 02000 #define IREAD 0400 #define IWRITE 0200 #define IEXEC 0100 int fin; int fout; int fso; int dlvl; char *charp; char *dptr; char dirstr[100]; char string[50]; char *pspec; char *proto; main(argc, argv) char **argv; { int i, c; char *a; /* * open relevent files */ if(argc != 3) { printf("arg count\n"); exit(); } pspec = argv[1]; proto = argv[2]; fin = open(pspec, 0); if(fin < 0) { printf("%s: cannot open\n", pspec); exit(); } fso = creat(proto, 0666); if(fso < 0) { printf("%s: cannot create\n", proto); exit(); } fout = fso; getstr(); printf("%s\n",string); /* boot file */ getstr(); printf("%s",string); /* file system size */ getstr(); printf(" %s\n",string); /* inode blocks */ getstr(); printf("%s",string); /* root directory flags */ getstr(); printf(" %s",string); /* root uid */ getstr(); printf(" %s\n",string); /* root gid */ while(c = getstr()) { if(string[c-1] == ':') { if(dlvl) { printf("\t$\n"); dlvl--; } string[c-1] = '\0'; if((c == 1) || (c == 2 && string[0] == '/')) continue; printf("%s\td--777 3 1\n",string); dlvl++; continue; } dptr = dirstr; a = string; while(*a) *dptr++ = *a++; *dptr = '\0'; cfile(dirstr); } if(dlvl) printf("\t$\n"); printf("$\n"); flush(); } cfile(dirp) char *dirp; { struct dirent { int ino; char name[14]; }dbuf; struct inode in; int dir, i; char *a; if(chdir(dirp) < 0) { flush(); fout = 1; printf("%s not a directory\n",dirstr); fout = fso; return; } if((dir = open(dptr,0)) < 0) { flush(); fout = 1; printf("can't open: %s\n",dirp); fout = fso; return; } while(read(dir,&dbuf,16) > 0) { if(dbuf.ino == 0) continue; if(dbuf.name[0] == '.' && dbuf.name[1] == '\0') continue; if(dbuf.name[0] == '.' && dbuf.name[1] == '.' && dbuf.name[2] == '\0') continue; stat(dbuf.name,&in); for(i = 0; i < dlvl; i++) printf("\t"); printf("%s\t",dbuf.name); if(in.i_mode&ISUID) string[1] = 'u'; else string[1] = '-'; if(in.i_mode&ISGID) string[2] = 'g'; else string[2] = '-'; string[3] = 060+((in.i_mode>>6)&07); string[4] = 060+((in.i_mode>>3)&07); string[5] = 060+(in.i_mode&07); switch(in.i_mode&IFMT) { case IFCHR: string[0] = 'c'; break; case IFBLK: string[0] = 'b'; break; case IFDIR: string[0] = 'd'; break; case 0: string[0] = '-'; } string[6] = '\0'; printf("%s",string); printf(" %d %d",in.i_uid,in.i_gid); switch(in.i_mode&IFMT) { case IFCHR: case IFBLK: printf(" %d %d\n",(in.i_addr[0]>>8)&0377,in.i_addr[0]&0377); break; case IFDIR: printf("\n"); dlvl++; a = dbuf.name; if(*(dptr-1) != '/') *dptr++ = '/'; while(*a) *dptr++ = *a++; *dptr = '\0'; cfile(dbuf.name); for(i = 0; i < dlvl; i++) printf("\t"); printf("$\n"); dlvl--; break; case 0: printf(" %s/%s\n",dirstr,dbuf.name); } } close(dir); while(dptr > dirstr) { if(*--dptr == '/') { if(dptr == dirstr) { dptr++; break; } else { *dptr = '\0'; break; } } *dptr = '\0'; } chdir(dirstr); } getstr() { int i, c; loop: switch(c=getchar()) { case ' ': case '\t': case '\n':  goto loop; case '\0': return(0); } i = 0; do { string[i++] = c; c = getchar(); } while(c!=' '&&c!='\t'&&c!='\n'&&c!='\0'); string[i] = '\0'; return(i); } case 0: printf(" %s/%s\n",dirstr,dbuf.name); } } close(dir); while(dptr > dirstr) { if(*--dptr == '/') { if(dptr == dirstr) { dptr++; break; } else { *dptr = '\0'; break; } } *dptr = '\0'; } chdir(dirstr); } getstr() { int i, c; loop: switch(c=getchar()) { case ' ': case '\t': case '\n': #define NMOUNT 16 #define NAMSIZ 32 struct mtab { char file[NAMSIZ]; char spec[NAMSIZ]; } mtab[NMOUNT]; main(argc, argv) char **argv; { register int ro; register struct mtab *mp; register char *np; int n, mf; mf = open("/etc/mtab", 0); read(mf, mtab, NMOUNT*2*NAMSIZ); if (argc==1) { for (mp = mtab; mp < &mtab[NMOUNT]; mp++) if (mp->file[0]) printf("%s on %s\n", mp->spec, mp->file); return; } if(argc < 3) { printf("arg count\n"); return; } ro = 0; if(argc > 3) ro++; if(mount(argv[1], argv[2], ro) < 0) { perror("mount"); return; } np = argv[1]; while(*np++) ; np--; while(*--np == '/') *np = '\0'; while(np > argv[1] && *--np != '/') ; if(*np == '/') np++; argv[1] = np; for (mp = mtab; mp < &mtab[NMOUNT]; mp++) { if (mp->file[0] == 0) { for (np = mp->spec; np < &mp->spec[NAMSIZ-1];) if ((*np++ = *argv[1]++) == 0) argv[1]--; for (np = mp->file; np < &mp->file[NAMSIZ-1];) if ((*np++ = *argv[2]++) == 0) argv[2]--; mp = &mtab[NMOUNT]; while ((--mp)->file[0] == 0); mf = creat("/etc/mtab", 0644); write(mf, mtab, (mp-mtab+1)*2*NAMSIZ); return; } } } '\0'; while(np > argv[1] && *--np != '/') ; if(*np == '/') np++; argv[1] = np; for (mp = mtab; mp < &mtab[NMOUNT]; mp++) { if (mp->file[0] == 0) { for (np = mp->spec; np < &mp->spec[NAMSIZ-1];) if ((*np++ = *argv[1]++) == 0) argv[1]--; for (np = mp->file; np < &mp->file[NAMSIZ-1];) if ((*np++ = *argv[2]++) == 0) argv[2]--; mp = &mtab[NMOUNT]/* Magnetic Tape Manipulation Program ** mtm [-sn] [-lm] [-bp] [unit] ** ** skip n files ** list m files ** buffer size pK bytes ** on unit ** ** Assumes definition of raw magnetic tapes and the ** mapping of 4-7 into physical drives 0-3 */ char *buf; int bcnt; int filecnt; int fd; int ccnt; int unit; char *file ; main(argc,argv) int argc; char *argv[]; { char *p; int nskip, nlist, skip, list; int finis(); signal(2,finis); signal(3,finis); unit = nskip = nlist = 0; skip = 0; list = 1; bcnt = 2; file = "/dev/rmt0 "; filecnt=1; argv++; while(--argc) { p = *argv++; if(*p == '-'){ ++p; switch(*p){ case 's': skip++; list--; nskip = atoi(++p); break; case 'l': list++; nlist = atoi(++p); break; case 'b': bcnt = atoi(++p); if(bcnt < 30) break; printf("Requested buffer too big %dK\n",bcnt); exit(8); default: printf("Bad option\n"); exit(8); } } else{ if((*p < '0') || (*p> '9')){ printf("Syntax Error\n");  exit(8); } unit = atoi(p); } } bcnt = bcnt<<10; if ((buf = sbrk(bcnt)) < 0) { printf("requested buffer too big - %dK\n",bcnt); exit(8); } unit = unit | 04; /* force to no rewind unit number */ ccnt = 1; if(unit > 9) ccnt = 2; itoa(unit,ccnt,&file[8]); if((fd = open(file, 0)) < 0) { printf("Tape Open Error %s\n",file); exit(8); } if(skip) files(nskip,0); if(list){ if(nlist == 0) nlist = -1; files(nlist,1); finis(); } } files(nfiles,lflag) int nfiles, lflag; { int cnt, prevcnt, reccnt, eof; if(nfiles == 0)return; eof=0; for(; nfiles--; filecnt++){ cnt = reccnt = prevcnt = 0; do{ prevcnt = cnt; if((cnt = read(fd,buf,bcnt)) == 0){ /* EOF */ if(eof){ /* double eof */ printf("Double EOF after file %d\n", --filecnt); finis(); } else{ eof=1; if(lflag) printf(" %d Records\n",reccnt); } } else{ eof = 0; if((++reccnt == 1) && lflag) printf("File %d:\n",filecnt); if(cnt<0){ /* error */ if(lflag) printf(" Record %d - ERROR\n",reccnt); } else{ /*data read*/ if(lflag && cnt != prevcnt) printf(" Record %d - %d bytes\n", reccnt,cnt); } } }while(eof==0); } } atoi(cp) char *cp; { int sum; int *minus; sum = minus =0; if(*cp == '-') { minus++; *cp++; } while (*cp <= '9' && *cp >= '0') { sum =* 10; sum =+ (*cp++ - '0'); } if(minus) sum = -sum; return(sum); } /* convert "numb" to "width" ASCII characters in "buf" with leading zeros. */ itoa(numb,width,array) char *array; { int i, *minus; minus = 0; i = width; while (i--) array[i] = '0'; if(numb < 0) { minus++; numb = -numb; } array[width] = '\0'; while(width) { array[--width] = numb%10 + '0'; numb =/ 10; } return(minus); } finis() { unit =- 4; ccnt = 1; if(unit > 9) ccnt = 2; itoa(unit,ccnt,&file[8]); close(fd); fd = open(file, 0); close(fd); printf("DONE\n"); exit(0); } ); } /* convert "numb" to "width" ASCII characters in "buf" with leading zero/* mv [-f] file1 file2 unlink file2 link file1 file2 unlink file1 */ int stbuf[42]; struct sbuf { int dev; int inum; int imode; char nlink; char uid; char gid; char siz0; char siz1; int addr[8]; int adate[2]; int mdate[2]; }; char strbuf[70]; main(argc,argv) int argc; char *argv[]; { char **argp; char *argp1, *argp2, *argp3, *argp4; char *p, *p1, *p2; char place[100]; char *arg; int fflg; int i; int status; int b; argp = argv; fflg = 0; arg = *++argv; /* check for optional argument */ if (arg[0] == '-') { argc--; if (arg[1] = 'f') { fflg++; argp = argv; }; } /* check for correct number of arguments */ if(argc != 3){ write(1,"Usage: mv name1 name2\n",22); exit(-1); } /* is there anything to do? */ argp3 = argp[1]; argp4 = argp[2]; if(stat(argp[1], stbuf) < 0){ write(1,"Source file non-existent\n",25); exit(-1); } /* yes, there is a source. check whether file or directory */ if((stbuf[0].imode & 060000) == 040000){ /* The source is a directory, so we do lots of checking and messing around so as not to get into trouble. This patch of code contains administrative policies rather than system restrictions. */ if(stat(argp[2], stbuf) >= 0){ write(1,"Directory target exists.\n",25); exit(-1); } argp1 = argp[1]; argp2 = argp[2]; while(*argp1 == *argp2){ argp1++; if(*argp2++ == 0){ write(1,"???\n",4); exit(-1); } } while(*argp1)if(*argp1++ == '/'){ write(1,"Directory rename only\n",22); exit(4); } while(*argp2)if(*argp2++ == '/'){ write(1,"Directory rename only\n",22); exit(4); } if(*--argp1 == '.'){ write(1,"values of B will give rise to dom!\n",37); exit(-1); } }else{ /* the source is a file. */ setuid(getuid()); if(stat(argp4, &stbuf[2]) >= 0){ if((stbuf[2].imode & 060000) == 040000){ argp2 = strbuf; while(*argp2++ = *argp4++); argp2[-1] = '/'; argp4 = argp[1]; argp1 = argp[1]; while(*argp4) if(*argp4++ == '/') argp1 = argp4; while(*argp2++ = *argp1++); argp4 = strbuf; } if(stat(argp4, &stbuf[2]) >= 0){ if((stbuf[0]==stbuf[2]) && (stbuf[1]==stbuf[3])){ write(1,"Files are identical.\n",21); exit(-1); } if(!fflg) { if((getuid()&0377) == stbuf[2].uid) b = 0200; else if((getgid()&0377) == stbuf[2].gid) b = 020; else b = 02; if((stbuf[2].imode & b) == 0) { printf("%s: %o mode ", argp4, stbuf[2].imode & 07777); i = b = getchar(); while(b != '\n' && b != '\0') b = getchar(); if(i != 'y') exit(-1); } } if(unlink(argp4) < 0){ write(1,"Cannot remove target file.\n",27); exit(-1); } } } } if(link(argp3, argp4) < 0){ i = fork(); if(i == -1){ write(1,"Try again.\n",11); exit(-1); } if(i){ while(wait(&status) != i); }else{ p = place; p1 = p; while(*p++ = *argp3++); p2 = p; while(*p++ = *argp4++); execl("/bin/cp","cp", p1, p2, 0); write(1, "no cp\n", 6); exit(-1); } if((status & 0377) != 0){ write(1,"?\n", 2); exit(-1); } if(status != 0) exit(-1); } if(unlink(argp3) < 0){ write(1,"Cannot unlink source file.\n",27); exit(-1); } exit(0); } putchar(c) { write(1, &c, 1); } getchar() { char c; if(read(0, &c, 1) != 1) return(0); return(c); } exit(-1); } if(i){ while(wait(&status) != i); }else{ p = place; p1 = p; while(*p++ = *argp3++); p2 = p; while(*p++ = *argp4++); execl("/bin/cp","cp", p1, p2, 0); write(1, "no cp\n", 6); exit(-1); } if((status & 0377) != 0){ write(1,"?\n", 2); exit(-1); } if(status != 0) exit(-1); } if(unlink(argp3) < 0){ write(1,"Cannot un/* nice */ char *args[100]; char string[10000]; main(argc, argv) int argc; char *argv[]; { int i; char **argp, *strp, *p; if(argc < 2) { printf("arg count\n"); exit(); } argc--; argv++; argp = args; strp = string; for (i=0; i<9; i++) *strp++ = "/usr/bin/"[i]; for(i=0; i0 && argv[1][0]=='-' && argv[1][1]!=0) { argv++; while (*++*argv) switch (**argv) { case 'n': nflg++; continue; case 'c': cflg++; continue; case 'g': gflg++; continue; case 'u': uflg++; continue; case 'r': rflg = -1; continue; case 'p':  pflg ++; continue; default: continue; } argc--; } if (argc==0) fi = open("a.out", 0); else fi = open(*++argv, 0); if(fi < 0) { write(2,"cannot open input\n",18); exit(1); } read(fi, buf, 020); if(buf[0]!=0405 && buf[0]!=0407 && buf[0]!=0410 && buf[0]!=0411) { write(2,"bad format\n",11); exit(2); } lseek(fi, 0, buf[1], 1); /* text */ lseek(fi, 0, buf[2], 1); /* data */ if(buf[7] != 1) { lseek(fi, 0, buf[1], 1); lseek(fi, 0, buf[2], 1); /* reloc */ } n = ldiv(0, buf[4], 12); if(n == 0) { write(2,"no name list\n",13); exit(3); } nlp = sbrk(12*n); read(fi, nlp, n*12); if (pflg==0) qsort(nlp, n, 12, compare); fout = dup(1); close(1); for(i=0; ityp&040)==0) goto out; if(cflg) { if(nlp->name[0] != '_') goto out; for(j=0; j<7; j++) nlp->name[j] = nlp->name[j+1]; nlp->name[7] = '\0'; } j = nlp->typ&037; if(j > 4) j = 1; if(j==0 && nlp->val) j = 5; if(uflg && j!=0) goto out; if(!uflg) {  if(j==0) printf(" "); else printo(nlp->val); printf("%c ", (nlp->typ&040? "UATDBC":"uatdbc")[j]); } printf("%.8s\n", nlp); out: nlp++; } flush(); exit(0); } compare(p1, p2) struct nl *p1, *p2; { int a, i; a = 0; if(nflg) { if(p1->val > p2->val) { a = 1; goto out; } if(p1->val < p2->val) { a = -1; goto out; } } for(i=0; i<8; i++) if(p1->name[i] != p2->name[i]) { if(p1->name[i] > p2->name[i]) a = 1; else a = -1; goto out; } out: return(a*rflg); } printo(v) { int i; printf("%c", v<0?'1':'0'); for(i=0; i<5; i++) { printf("%c", ((v>>12)&7)+'0'); v =<<3; } } f("%.8s\n", nlp); out: nlp++; } flush(); exit(0); } compare(p1, p2) struct nl *p1, *p2; { int a, i; a = 0; if(nflg) { if(p1->val > p2->val) { a = 1; goto out; } if(p1->val < p2->val) { a = -1; goto out; } } for(i=0; i<8; i++) if(p1->name[i] != p2->name[i]) { if(p1->name[i] > p2->name[i]) a = 1; else a = -1; goto out; } out: return(a*/* nohup */ char *args[100]; char string[10000]; main(argc, argv) int argc; char *argv[]; { int i; char **argp, *strp, *p; if(argc < 2) { printf("arg count\n"); exit(); } argc--; argv++; argp = args; strp = string; for (i=0; i<9; i++) *strp++ = "/usr/bin/"[i]; for(i=0; i 1) { p = *argv; if(*p++== '-') { while((i = *p++) != '\0') { switch(i) { case 'o': conv =| 001; f = 6; break; case 'd': conv =| 002; f = 5; break; case 'a': conv =| 004; f = 4; break; case 'h': conv =| 010; f = 4; break; case 'c': conv =| 020; f = 5; break; case 'b': conv =| 040; f = 7; break; } if(f > max) max = f; } argc--; argv++; } } if(!conv) { max = 6; conv = 1; } if(argc > 1) if(**argv != '+') { fi = open(*argv, 0); if(fi < 0) { printf("cannot open %s\n", *argv); goto done; } argv++; argc--; } if(argc > 1) offset(*argv); loop: f = 1; a[0] = addr[0]; a[1] = addr[1]; for(i=0; i>8); break; case 040: pre(7); putn(n&0377, 8, 3); putchar(' '); putn((n>>8)&0377, 8, 3); break; } } getw() { int b1, b2; b1 = getc(); if(b1 == -1) { eof = 1; return(0); } b2 = getc(); if(b2 == -1) b2 = 0; return(b1|(b2<<8)); } getc() { if(gidx >= gcnt) { gcnt = read(fi, gbuf, 512); if(gcnt <= 0) return(-1); gidx = 0; } if(++addr[1] >= basem) { addr[0]++; addr[1] = 0; } return(gbuf[gidx++]&0377); } putc(c) { c =& 0377; if(c>037 && c<0177 && c!='\\') { putchar(' '); putchar(c); return; } putchar('\\'); switch(c) { case '\0': putchar('0'); break; case '\n': putchar('n'); break; case '\\': putchar('\\'); break; case '\t': putchar('t'); break; default: putchar('?'); } } putn(n, b, c) { if(!c) return; putn(ldiv(0,n,b),b,c-1); if((n=lrem(0,n,b)) > 9) putchar(n-10+'a'); else putchar(n+'0'); } pre(n) { int i; for(i=n; i 0) if(p[-2] == 'b') { i--; b++; p--; } if(i > 0) if(p[-2] == '.') { i--; base = 10; basem = 1000; } a[0] = 0; for(j=0; i-j>3; j++) { d = s[j]; if(d>='0' && d<='9') a[0] = a[0]*base + d-'0'; } a[1] = 0; for(; i-j>0; j++) { d = s[j]; if(d>='0' && d<='9') a[1] = a[1]*base + d-'0'; } if(b) { i = a[0]*basem+a[1]; a[0] = 0; a[1] = 0; while(i--) { a[1] =+ 512; while(a[1] >= basem) { a[1] =- basem; a[0]++; } } } i = 0; while(a[0] > addr[0]+1) { addr[1] =+ 512; while(addr[1] >= basem) { addr[1] =- basem; addr[0]++; } i++; } seek(fi, i, 3); while(a[0]!=addr[0] || a[1]!=addr[1]) if(getc() == -1) break; } putop(n) { char *p; int i, c; p = getop(n); for(i=0; (c = *p++) != '\0'; i++) putchar(c); for(; i<4; i++) putchar(' '); } getop(n) { switch(n&0170000) { case 0000000: switch(n&0177000) { case 0004000: return("jsr"); case 0077000: return("sob"); } switch(n&0177400) { case 0000400: return("br"); case 0001000: return("bne"); case 0001400: return("beq"); case 0002000: return("bge"); case 0002400: return("blt"); case 0003000: return("bgt"); case 0003400: return("ble"); } switch(n&0177700) { case 0000100: return("jmp"); case 0000300: return("swab"); case 0005000: return("clr"); case 0005100: return("com"); case 0005200: return("inc"); case 0005300: return("dec"); case 0005400: return("neg"); case 0005500: return("adc"); case 0005600: return("sbc"); case 0005700: return("tst"); case 0006000: return("ror"); case 0006100: return("rol"); case 0006200: return("asr"); case 0006300: return("asl"); case 0006400: return("mark"); case 0006500: return("mfpi"); case 0006600: return("mtpi"); case 0006700: return("sxt"); } switch(n&0177740) { case 0000240: return("flag"); } switch(n&0177770) { case 0000200: return("rts"); case 0000230: return("spl"); } switch(n&0177777) { case 0000000: return("halt"); case 0000001: return("wait"); case 0000002: return("rti"); case 0000003: return("bpt"); case 0000004: return("iot"); case 0000005: return("rset"); case 0000006: return("rtt"); } break; case 0010000: return("mov "); case 0020000: return("cmp"); case 0030000: return("bit"); case 0040000: return("bic"); case 0050000: return("bis"); case 0060000: return("add"); case 0070000: switch(n&0177000) { case 0070000: return("mul"); case 0071000: return("div"); case 0072000: return("ash"); case 0073000: return("ashc"); case 0074000: return("xor"); } break; case 0100000: switch(n&0177400) { case 0100000: return("bpl"); case 0100400: return("bmi"); case 0101000: return("bhi"); case 0101400: return("blos"); case 0102000: return("bvc"); case 0102400: return("bvs"); case 0103000: return("bhis"); case 0103400: return("blo"); case 0104000: return("emt"); case 0104400: return("sys"); } switch(n&0177700) { case 0105000: return("clrb"); case 0105100: return("comb"); case 0105200: return("incb"); case 0105300: return("decb"); case 0105400: return("negb"); case 0105500: return("adcb"); case 0105600: return("sbcb"); case 0105700: return("tstb"); case 0106000:  return("rorb"); case 0106100: return("rolb"); case 0106200: return("asrb"); case 0106300: return("aslb"); case 0106500: return("mfpd"); case 0106600: return("mfpd"); } break; case 0110000: return("movb"); case 0120000: return("cmpb"); case 0130000: return("bitb"); case 0140000: return("bicb"); case 0150000: return("bisb"); case 0160000: return("sub"); case 0170000: switch(n&0177000) { case 0:0; } break; } return("???"); } e 0106000: # #define ERROR 0 #define PAD 10 #define NULL 0 char *dargv[] { "/dev/rroot", "/dev/rrusr", "/dev/rsrc", 0 }; int pass1(); int pass2(); int pass3(); #define NINODE 16*16 #include "../head/ino.h" #include "../head/filsys.h" struct filsys sblock; struct inode inode[NINODE]; int sflg; int aflg; int uflg; int uid; int nufile; #define NI 20 #define NDIRS 787 struct ilist{ int inum; int size; }; struct ilist *ilist; struct ilist *ulist; struct user{ int id; char *uname; }; struct user *user; int nuser; int ic; int nilist; int nulist; int fi; struct htab { int hino; int hpino; char hname[14]; } ; struct htab *htab; int hsize; int nhent PAD; int (*pass[])() { pass1, pass2, pass3 }; char *lasts; int ino; int nerror; int nffil; int fout; int nfiles; struct dir { int ino; char name[14]; }; int ndir; int try; int error; int first; int ufirst; int carg; char cbuf[518]; char pbuf[128]; int ac; char **av; int lim; char *nm; main(argc, argv) char **argv; { register char **p; struct user *up,*uup; int i; char *q; register int n; register struct ilist *lp; struct ilist *llp; /* nffil = dup(1); */ carg = argc; lim = 1; if(carg == 3) lim = 0; ac = argc; av = argv; if (ac == 1) { for (p = dargv; *p;) check(*p++); return(nerror); } while (--ac) { av++; if (**av=='-') switch ((*av)[1]) { case 's': sflg++; continue; case 'a': aflg++; continue; case 'i': if(first == 0){ if(carg == 3) nilist = 512; else nilist = ac; first++; ilist = alloc(sizeof(ilist[0])*nilist); llp = &ilist[nilist-1]; nilist = 1; lp = ilist; } av++; ac--; while((ac>lim)&&(q = token())&&(lpinum = n; lp++; nilist++; }else break; } lp->inum = -1; ac++; av--; if(lp == ilist){ printf2("I-node numbers?\n"); exit(1); } continue; case 'u': uflg++; if(ufirst == 0){ ufirst++; user = alloc(129*sizeof(user[0])); nuser = 1; up = user; uup = &user[129]; } ac--; av++; while((ac>lim)&&(q = token())&&(upid = n; up->uname = alloc(n = length(nm)+1); copy(up->uname,nm,n); nuser++; up++; }else{ printf("%s unknown user\n",q); } } up->id = -1; ac++; av--; if(up == user){ printf2("User id's?\n"); exit(1); } continue; default: printf2("Bad flag\n"); } if(ilist == NULL){ ilist = alloc(sizeof(ilist[0])); ilist[0].inum = -1; } check(*av); } return(nerror); } char lbuf[128]; token() { register char *p; register char c; if(carg != 3){ return(*av); } p = lbuf; while((c = getc(cbuf)) >=0){ switch(c){ case ' ': case '\t': case '\n': goto out; default: *p++ = c; if(p > &lbuf[128]){ printf2("Line buffer exceeded\n"); lbuf[0] = '\0'; goto out;  } } } if(p == lbuf) return(NULL); out: *p = '\0'; return(&lbuf); } check(file) char *file; { register i, j; int pno; register struct inode *ip; int k; int n,s,o; htab = alloc((NDIRS+PAD)*sizeof(htab[0])); hsize = NDIRS + PAD; init(); fi = open(file, 0); if (fi < 0) { printf2("cannot open %s\n", file); return; } printf2("%s:\n", file); sync(); bread(1, &sblock, 512); nfiles = sblock.s_isize*16; fout = nffil; flush(); try = 0; retry: nufile = 0; nhent = PAD; error = 0; if((try == 0)&&uflg) error++; ndir = 0; ino = 0; for(i=0; i=hsize){ printf2("Rescan necessary: %d. directories\n",ndir); free(htab); hsize = PAD + ndir + (ndir/5); htab = alloc((PAD + ndir + (ndir/5))*sizeof(htab[0])); init();  } try++; goto retry; } if(uflg){ ulist = alloc((nufile+15)*sizeof(ulist[0])); nulist = nufile+2; } for (pno=1; pno<3; pno++) { ino = 0; for (i=0; inoi_uid&0377) == user[k].id)&& ((ip->i_mode&IALLOC) != 0)){ ulist[ic].inum = ino; s = (ip->i_size1 >> 9) & 0177; s =| (ip->i_size0 << 7) & 077600; if(ip->i_size1 & 0777) s++; if(s > 8) { o = (s >> 8) & 0377; if(s & 0377) o++; /* huge files if(o > 7) o++; */ s =+ o; } ulist[ic++].size = s; break; } } (*pass[pno])(ip); } } if(uflg) ulist[ic].inum = -1; } flush(); fout = 1; } pass1(ip) struct inode *ip; { register struct user *u; if ((ip->i_mode&IALLOC)==0) return(1); if(uflg){ for(u=user;u<&user[nuser];u++){  if((ip->i_uid&0377) == u->id){ nufile++; break; } } } if((ip->i_mode&IFMT)!=IFDIR) return(1); ndir++; return(lookup(ino, 1)); } pass2(ip) struct inode *ip; { register doff; register struct htab *hp; register struct dir *dp; int i; if ((ip->i_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; doff = 0; while (dp = dread(ip, doff)) { doff =+ 16; if (dp->ino==0) continue; if ((hp = lookup(dp->ino, 0)) == 0) continue; if (dotname(dp)) continue; hp->hpino = ino; for (i=0; i<14; i++) hp->hname[i] = dp->name[i]; } } pass3(ip) struct inode *ip; { int doff; register struct dir *dp; register struct ilist *ilp,*ulp; char b[512]; int o; int i; struct inode *p; struct user *up; long tell(); if ((ip->i_mode&IALLOC)==0 || (ip->i_mode&IFMT)!=IFDIR) return; doff = 0; while (dp = dread(ip, doff)) { doff =+ 16; if (dp->ino==0) continue; if (aflg==0 && dotname(dp)) continue; for (ilp=ilist; ilp->inum >= 0; ilp++) if (ilp->inum == dp->ino) break; if((ilp->inum == -1)&&(aflg == 0)) goto uf; printf("%d ", dp->ino); pname(ino, 0); printf("/%.14s\n", dp->name); uf: if(uflg){ for (ulp=ulist; ulp->inum >= 0; ulp++) if (ulp->inum == dp->ino) break; if(ulp->inum == -1) continue; printf("%d\t", dp->ino); printf("%d\t",ulp->size); if(nuser>2){ o = dp->ino + 31; if(seek(fi,o>>4,3)<0) printf2("Can't seek\n"); read(fi,&b,sizeof(b)); p = &b[(o%16)*32]; for(up=user;up<&user[nuser];up++)  if(up->id == (p->i_uid&0377)){ printf("%-7.7s\t",up->uname); break; } }else printf("%-7.7s\t",user[0].uname); pname(ino, 0); printf("/%.14s\n", dp->name); } } } dotname(adp) { register struct dir *dp; dp = adp; if (dp->name[0]=='.') if (dp->name[1]==0 || dp->name[1]=='.' && dp->name[2]==0) return(1); return(0); } pname(i, lev) { register struct htab *hp; if (i==1) return; if ((hp = lookup(i, 0)) == 0) { printf("???"); return; } if (lev > 10) { printf("..."); return; } pname(hp->hpino, ++lev); printf("/%.14s", hp->hname); } lookup(i, ef) { register struct htab *hp; for (hp = &htab[i%hsize]; hp->hino;) { if (hp->hino==i) return(hp); if (++hp >= &htab[hsize]) hp = htab; } if (ef==0) return(0); if (++nhent >= hsize) { return(ERROR); } hp->hino = i; return(hp); } dread(aip, aoff) { register b, off; register struct inode *ip; static ibuf[256]; static char buf[512]; off = aoff; ip = aip; if ((off&0777)==0) { if (off==0177000) { printf2("Monstrous directory %l\n", ino); return(0); } if ((ip->i_mode&ILARG)==0) { if (off>=010000 || (b = ip->i_addr[off>>9])==0) return(0); bread(b, buf, 512); } else { if (off==0) { if (ip->i_addr[0]==0) return(0); bread(ip->i_addr[0], ibuf, 512); } if ((b = ibuf[(off>>9)&0177])==0) return(0); bread(b, buf, 512); } } return(&buf[off&0777]); } bread(bno, buf, cnt) { seek(fi, bno, 3); if (read(fi, buf, cnt) != cnt) { printf2("read error %d\n", bno); exit(); } } bwrite(bno, buf) { seek(fi, bno, 3); if (write(fi, buf, 512) != 512) { printf2("write error %d\n", bno); exit(); } } number(as) char *as; { register n, c; register char *s; s = as; n = 0; while ((c = *s) >= '0' && c <= '9') { n = n*10+ *s++ -'0'; } if(s == as) return(-1); return(n); } printf2(s, a1, a2) { extern fout; flush(); fout = 2; printf(s, a1, a2); fout = nffil; flush(); } init() { register i; for(i=0;i>12 ); } prs(s) register char *s; { while(*s) write(2, s++, 1); } (" is not an ordinary file.\n"); } else if(fork() == 0) { execl("/bin/m/ passwd -- change user's password .globl mesg .globl crypt .globl getc .globl flush .globl fcreat .globl putc .globl fopen cmp (sp)+,$3 bge 1f jsr r5,mesg ; .even sys exit 1: tst (sp)+ mov (sp)+,uidp mov (sp)+,r0 tstb (r0) beq 1f jsr pc,crypt clrb 8(r0) 1: mov r0,cryptp mov $passwf,r0 jsr r5,fopen; ibuf bec 1f jsr r5,mesg ; .even sys exit 1: sys stat; tempf; obuf+20. bec 2f sys creat; tempf; 222 bec 1f 2: jsr r5,mesg ; .even sys exit 1: mov r0,obuf / search for uid comp: mov uidp,r1 1: jsr pc,pcop cmp r0,$': beq 1f cmpb r0,(r1)+ beq 1b 2: jsr pc,pcop cmp r0,$'\n bne 2b br comp 1: tstb (r1)+ bne 2b / skip over old password 1: jsr pc,pget cmp r0,$': bne 1b / copy in new password mov cryptp,r1 1: movb (r1)+,r0 beq 1f jsr pc,pput br 1b 1: mov $':,r0 jsr pc,pput / validate permission clr r1 1: jsr pc,pcop cmp r0,$': beq 1f mpy $10.,r1 sub $'0,r0 add r0,r1 br 1b 1: sys getuid tst r0 beq 1f cmp r0,r1 beq 1f jsr r5,mesg ; .even br done 1: inc sflg 1: jsr pc,pcop br 1b done: jsr r5,flush; obuf mov obuf,r0 sys close mov ibuf,r0 sys close tst sflg beq 1f tst dflg bne 1f inc dflg mov $tempf,r0 jsr r5,fopen; ibuf bec 2f jsr r5,mesg ; .even br 1f 2: mov $passwf,r0 jsr r5,fcreat; obuf bec 2f jsr r5,mesg ; .even br 1f 2: jsr pc,pcop br 2b 1: sys unlink; tempf sys exit pput: jsr r5,putc; obuf rts pc pget: jsr r5,getc; ibuf bes 1f rts pc 1: jsr r5,mesg ; .even br done pcop: jsr r5,getc; ibuf bes 1f jsr r5,putc; obuf rts pc 1: tst sflg bne 1f jsr r5,mesg ; .even 1: br done .data passwf: tempf: .even .bss ibuf: .=.+520. obuf: .=.+520. cryptp: .=.+2 uidp: .=.+2 sflg: .=.+2 dflg: .=.+2 assword file\n\0>; .even br 1f 2: jsr pc,pcop br 2b 1:/ print last floating error stst = 170300^tst stst r1 cmp r1,$14 blos 1f clr r1 1: bic $1,r1 mov mesg(r1),r1 1: movb (r1)+,ch beq 1f mov $1,r0 sys write; ch; 1 br 1b 1: sys exit mesg: 1f 2f 3f 4f 5f 6f 7f 8f 1: 2: 3: 4: 5: 6: 7: 8: .even .bss ch: .=.+2 sr pc,pcop br 2b 1:# /* * print file with headings * 2+head+2+page[56]+5 */ int ncol 1; char *header; int col; int icol; int file; char *bufp; #define BUFS 5120 char buffer[BUFS]; #define FF 014 int line; char *colp[72]; int nofile; char isclosed[10]; int peekc; int fpage; int page; int colw; int nspace; int width 72; int length 66; int plength 61; int margin 10; int ntflg; int mflg; int tabc; char *tty; int mode; struct inode { int dev; int inum; int flags; char nlink; char uid; char gid; char siz0; int size; int ptr[8]; int atime[2]; int mtime[2]; }; main(argc, argv) char **argv; { int nfdone; int onintr(); extern fout; tty = "/dev/ln\0\0"; fout = dup(1); close(1); if ((signal(2, 1) & 01) == 0) signal(2, onintr); fixtty(); for (nfdone=0; argc>1; argc--) { argv++; if (**argv == '-') { switch (*++*argv) { case 'h': if (argc>=2) { header = *++argv; argc--; } continue; case 't': ntflg++; continue; case 'l': length = getn(++*argv); continue; case 'w': width = getn(++*argv); continue; case 's': if (*++*argv) tabc = **argv; else tabc = '\t'; continue; case 'm': mflg++; continue; default: ncol = getn(*argv); continue; } } else if (**argv == '+') { fpage = getn(++*argv); } else { print(*argv, argv); nfdone++; if (mflg) break; } } if (nfdone==0) print(0); flush(); onintr(); } onintr() { chmod(tty, mode); exit(0); } fixtty() { struct inode sbuf; extern fout; register ln; ln = lnxx(fout); tty[7] = ln; tty[8] = ln>>8; fstat(fout, &sbuf); mode = sbuf.flags&0777; chmod(tty, 0600); } print(fp, argp) char *fp; char **argp; { struct inode sbuf; register int sncol, sheader; register char *cbuf; extern fout; if (ntflg) margin = 0; else margin = 10; if (length <= margin) length = 66; if (width <= 0) width = 72; if (ncol>72 || ncol>width) { write(2, "Very funny.\n", 12); exit(); } if (mflg) { mopen(argp); ncol = nofile; } colw = width/ncol; sncol = ncol; sheader = header; plength = length-5; if (ntflg) plength = length; if (--ncol<0) ncol = 0; if (mflg) fp = 0; if (fp) { file = open(fp, 0); if (file<0) return; fstat(file, &sbuf); } else { file = 0; time(sbuf.mtime); } if (header == 0) header = fp; cbuf = ctime(sbuf.mtime); cbuf[16] = '\0'; page = 1; icol = 0; colp[ncol] = bufp = buffer; if (mflg==0) nexbuf(); while (mflg&&nofile || (!mflg)&&tpgetc(ncol)>0) { if (mflg==0) { colp[ncol]--; if (colp[ncol] < buffer) colp[ncol] = &buffer[BUFS]; } line = 0; if (ntflg==0) { puts("\n\n"); puts(cbuf+4); puts(" "); puts(header); puts(" Page "); putd(page); puts("\n\n\n"); } putpage(); if (ntflg==0) while(line=10) {  write(2, "Too many args.\n", 15); exit(); } } } putpage() { register int lastcol, i, c; int j; if (ncol==0) { while (line512) n = 512; if ((n = read(file, rbufp, n)) <= 0) *rbufp = 0376; else { rbufp =+ n; if (rbufp >= &buffer[BUFS])  rbufp = buffer; *rbufp = 0375; } bufp = rbufp; } tpgetc(ai) { register char **p; register int c, i; i = ai; if (mflg) { if ((c = getc(&buffer[2*259*i])) < 0) { if (isclosed[i]==0) { isclosed[i] = 1; if (--nofile <= 0) return(0); } return('\n'); } if (c==FF && ncol>0) c = '\n'; return(c); } loop: c = **(p = &colp[i]) & 0377; if (c == 0375) { nexbuf(); c = **p & 0377; } if (c == 0376) return(0); (*p)++; if (*p >= &buffer[BUFS]) *p = buffer; if (c==0) goto loop; return(c); } pgetc(i) { register int c; if (peekc) { c = peekc; peekc = 0; } else c = tpgetc(i); if (tabc) return(c); switch (c) { case '\t': icol++; if ((icol&07) != 0) peekc = '\t'; return(' '); case '\n': icol = 0; break; case 010: case 033: icol--; break; } if (c >= ' ') icol++; return(c); } puts(as) char *as; { register int c; register char *s; if ((s=as)==0) return; while (c = *s++) put(c); } putd(an) { register int a, n; n = an; if (a = n/10) putd(a); put(n%10 + '0'); } put(ac) { register int ns, c; c = ac; if (tabc) { putcp(c); if (c=='\n') line++; return; } switch (c) { case ' ': nspace++; col++; return; case '\n': col = 0; nspace = 0; line++; break; case 010: case 033: if (--col<0) col = 0; if (--nspace<0) nspace = 0; } while(nspace) { if (nspace>2 && col > (ns=((col-nspace)|07))) { nspace = col-ns-1; putcp('\t'); } else { nspace--; putcp(' '); } } if (c >= ' ') col++; putcp(c); } getn(ap) char *ap; { register int n, c; register char *p; p = ap; n = 0; while ((c = *p++) >= '0' && c <= '9') n = n*10 + c - '0'; return(n); } putcp(c) { if (page >= fpage) putchar(c); } l = 0; nspace = 0; line++; break; case 010: case 033: if (--col<0) col = 0; if (--nspace<0) nspace = 0; } while(nspace) { if (nspace>2 && col > (ns=((col-nspace)|07))) { nspace = col-ns-1; putcp('\t'); } else { nspace--; putcp(' '); } } if (c >= ' ') col++/* * Print execution profile */ struct nl { char name[8]; int value; float time; int ncall[2]; }; struct nl nl[200]; struct fnl { char fname[8]; int flag; int fvalue; }; struct cnt { int cvalue; int cncall[2]; } cbuf[200]; struct inode { int idev; int inum; int flags; char nlink; char uid; char gid; char size0; int size; int ptr[8]; int ctime[2]; int mtime[2]; int fill; }; int buf[17]; int i; int j; int highpc; int lowpc; int ccnt; int pcl; int pch; int bufs; int nname; double time; double totime; double maxtime; double scale; double lastx; double lasty; struct nl *np; struct nl *npe; int aflg; int vflg; int lflg; int symoff; int symsiz; int vf; int fout; int ncount; main(argc, argv) char **argv; { char *namfil; int timcmp(), valcmp(); int nf, pf, overlap; double fnc, ltod(); struct cnt *cp; fout = dup(1); argv++; namfil = "a.out"; while (argc>1) { if (**argv == '-') { if (*++*argv == 'l') lflg++; if (**argv == 'a') aflg = 040; if(**argv == 'v') vflg++; } else namfil = *argv; argc--; argv++; } if ((nf = open(namfil, 0)) < 0) { printf("Can't find %s\n", namfil); done(); } read(nf, buf, 020); if (buf[0] != 0407 && buf[0] != 0410) { /* a.out magic */ printf("Bad format: %s\n", namfil); done(); } symsiz = buf[4]; symoff = buf[1] + buf[2]; if (buf[7] != 1) symoff =<< 1; seek(nf, symoff+020, 0); if ((pf = open("mon.out", 0)) < 0) { printf("No mon.out\n"); done(); } fstat(pf, buf); read(pf, &lowpc, 2); read(pf, &highpc, 2); read(pf, &ncount, 2); bufs = buf->size/2 - 3*(ncount+1); read(pf, cbuf, ncount*6); lowpc = (lowpc>>1) & 077777; highpc = (highpc>>1) & 077777; npe = nl; for (nname = 0; symsiz > 0; symsiz =- 12) { read(nf, buf, 12); if ((buf->flag | aflg) != 042) continue; buf->fvalue = (buf->fvalue>>1) & 077777; npe->value = buf->fvalue; for (i=0; i<8; i++) npe->name[i] = buf->fname[i]; npe++; nname++; } if (nname == 0) { printf("No symbols: %s\n", namfil); done(); } npe->value = 077777; npe++; for (cp = cbuf; cp < &cbuf[ncount]; cp++) for (np = nl; np < npe; np++) if (cp->cvalue-8 == np->value<<1) { np->ncall[0] = cp->cncall[0]; np->ncall[1] = cp->cncall[1]; break; } qsort(nl, nname, 18, &valcmp); scale = (highpc-lowpc)/(bufs+0.0); for (i = -1; read(pf, &ccnt, 2)==2; i++) { if (ccnt == 0) continue; time = ccnt; if (ccnt<0) time =+ 65536.; totime =+ time; if(time > maxtime) maxtime = time; pcl = lowpc + scale*i; pch = lowpc + scale*(i+1); for (j=0; j= nl[j+1].value) continue; overlap=(min(pch,nl[j+1].value)-max(pcl,nl[j].value)); nl[j].time =+ overlap*time/scale; } } if (totime==0.0) { printf("No time accumulated\n"); done(); } if(!vflg) goto print; vf = open("/dev/vt0", 1); if(vf < 0) { printf("Cannot open vt\n"); done(); } fout = vf; vtch(1); vtch(1); vtch(3); point(-2048., -2048.); point(-2048., 2048.); vtch(3); point(0., -2048.); point(0., 2048.); for(j=0; j<9; j++) { vtch(3); point(-2048., 2048. - j*512.); point(0., 2048. - j*512.); } lastx = 0.; lasty = 2048.; scale = 4096./(i-1); seek(pf, 6*(ncount+1), 0); while(read(pf, &ccnt, 2)==2) { time = ccnt; if(ccnt < 0) time =+ 65536.; vtch(3); point(lastx, lasty); lastx = -time*2000./maxtime; point(lastx, lasty); vtch(3); point(lastx, lasty); lasty =- scale; point(lastx, lasty); } scale = 4096./(highpc-lowpc); lastx = 50.; for(np = nl; npvalue < lowpc) continue; if(np->value >= highpc) continue; time = np->time/totime; lasty = 2048. - (np->value - lowpc)*scale; vtch(3); point(0., lasty); point(50., lasty); vtch(3); point(lastx-50., lasty); point(lastx, lasty); vtch(9); point(lastx+10., lasty+60.); vtch(1); vtch(3); for(j=0; j<8; j++) if(np->name[j] != '_') vtch(np->name[j]); vtch(0); lastx =+ 500.; if(lastx > 2000.) lastx = 50.; } done(); print: printf(" name %%time #call  ms/call\n"); if (!lflg) qsort(nl, nname, 18, &timcmp); for (np = nl; nptime/totime; printf("%8.8s%6.1f", np->name, 100*time); fnc = ltod(np->ncall); if (fnc != 0.0) { printf("%6s", locv(np->ncall[0], np->ncall[1])); printf(" %7.2f\n", np->time/(fnc*.06)); } else printf("\n"); } done(); } min(a, b) { if (ab) return(a); return(b); } valcmp(p1, p2) struct nl *p1, *p2; { return(p1->value - p2->value); } timcmp(p1, p2) struct nl *p1, *p2; { float d; d = p2->time - p1->time; if (d > 0.0) return(1); if (d < 0.0) return(-1); return(0); } vtch(c) int c; { putchar(c&0377); } point(x, y) float x, y; { point1(x); point1(y); } point1(xy) float xy; { int ixy; struct { char b1; char b2;}; if(xy > 2047.) xy = 2047.; if(xy < -2048.) xy = -2048.; ixy = xy; vtch(ixy.b1); vtch(ixy.b2); } done() { flush(); exit(); } valcmp(p1, p2) struct nl *p1, *p2; { return(p1->value - p2->value); # /* * ps - process status * examine and print certain things about processes */ #include #include #include #include #define EGOOD 0 #define EBAD 1 #define NONEWLINE 0 #define NEWLINE 1 #define OUTPUT 1 struct { char lobyte; char hibyte; }; struct { char name[8]; int type; char *value; } nl[4]{ "_proc", 0, 0, "_swapdev", 0, 0, "_syspara", 0, 0, "\0\0\0\0\0\0\0\0", 0, 0 }; struct proc mproc[1]; int ua[256]; int chkpid; int lflg; int nflg; int cflg; int xflg; int tflg; int aflg; int mem; int swmem; int swap; char swapnam[20]; int nproc NPROC; int ndev; int devc[65]; int devl[65]; char *coref; char *unix "/unix"; int swapdev; struct ibuf { char idevmin, idevmaj; int inum; int iflags; char inl; char iuid; char igid; char isize0; int isize; int iaddr[8]; char *ictime[2]; char *imtime[2]; int fill; }; char partab[1]; main(argc, argv) char **argv; { struct proc *p; int n, b; int i, c; char *ap,*aq; int uid, puid; extern fout; argc--; argv++; if (argc>0 && *argv[0] == '-') { ap = argv[0]; while (*ap) switch (*ap++) { case 'a': aflg = 1; break; case 't': /* Processes of a given teletype */ aq = argv[1]; argv++; argc--; if(*aq) tflg.lobyte = *aq++; if(*aq) tflg.hibyte = *aq++; aflg++; if(tflg == '?') xflg++; break; case 'x': /* All processes */ xflg++; if(aflg == 0) aflg = 20; break; case '-': break; case 'l': /* Long listing */ lflg++; break; case 's': /* Namelist other that /unix */ nflg++; break; default: chkpid=atoi(--ap); *ap = '\0'; break; } argc--; argv++; } if(nflg){ unix = argv[argc-1]; } if(nlist(unix, nl) <0){ printf("No namelist\n"); done(EBAD); } coref = "/dev/mem"; if(((argc>=1)&&(nflg == 0))||((argc>=2)&&nflg)){ coref = argv[0]; cflg++; } if ((mem = open(coref, 0)) < 0) { printf("Can't open %s\n",coref); done(EBAD); } swmem = open(coref, 0); if(chdir("/dev") < 0) { write(2,"cannot change to /dev\n",22); done(EBAD); } /* * read mem to find swap dev. */ if((seek(mem, nl[1].value, 0)<0)|| (read(mem, &swapdev, 2) != 2)){ printf("No swapdev\n"); } /* * read number of processes */ if(nl[2].type > 0){ seek(mem,nl[2].value,0); read(mem,nproc,2); } /* * Locate proc table */ if(seek(mem, nl[0].value, 0)<0){ printf("Can't seek to proc table \n"); done(EBAD); } getdev(); uid = getuid() & 0377; fout = dup(OUTPUT); if (lflg){ printf("swap device %s\n",swapnam); printf(" F S UID PID PPID CPU PRI NICE ADDR SZ WCHAN LNE TIME COMMAND\n"); }else if (chkpid==0) printf(" PID LNE TIME COMMAND\n"); for (i=0; idir_ino == 0) continue; if(p->dir_n[0] == 'l' && p->dir_n[1] == 'n' && p->dir_n[2] != 0 && p->dir_n[4] == 0) { if(stat(p->dir_n, sbuf) < 0) continue; devc[c].lobyte = p->dir_n[2]; devc[c].hibyte = p->dir_n[3]; devl[c] = sbuf->iaddr[0]; c++; continue; } if(swap >= 0) continue; if(stat(p->dir_n, sbuf) < 0) continue; if((sbuf->iflags & 060000) != 060000) continue; if(sbuf->iaddr[0] == swapdev){ swapdev = -1; if(cflg){ if((swap = open("/dev/null",0))<0){ printf("No null device\n"); } }else{ if((swap = open(p->dir_n, 0))<0){ printf("Can't open %s\n",p->dir_n); } } copy(swapnam,"/dev/",5); copy(&swapnam[5],p->dir_n,14); } } goto loop; } prcom(puid) { int mf; register int *ip; register char *cp, *cp1; long tm; int c, nbad; long o,oc; o = mproc[0].p_addr; if (mproc[0].p_flag&SLOAD) { mf = swmem; o =<< 6; } else { mf = swap; o =<< 9; if(swap<0) return(NONEWLINE); } lseek(mf, o, 0); if (read(mf, &ua[0], 512) != 512) return(NONEWLINE); c = gettty(); if(tflg && c != tflg) return(NONEWLINE); if (lflg) { if(mproc[0].p_wchan&&(mproc[0].p_pri > 0)) printf("%2o %c%4d", mproc[0].p_flag, 'W' ,puid); else printf("%2o %c%4d", mproc[0].p_flag, "0SWRIZT"[mproc[0].p_stat], puid); } printf("%6u", mproc[0].p_pid); if (lflg) { printf("%6u%4d%4d%5d %5o%4d", mproc[0].p_ppid, mproc[0].p_cpu&0377, mproc[0].p_pri, mproc[0].p_nice, mproc[0].p_addr, (mproc[0].p_size+7)>>3); if (mproc[0].p_wchan) printf("%7o", mproc[0].p_wchan); else printf(" "); } printf(" %c%c", c.lobyte,c.hibyte); if (mproc[0].p_stat==5) { printf(" "); return(NEWLINE); } if(cflg&&((mproc[0].p_flag&SLOAD) == 0)) return(NEWLINE); tm = (ua[0].u_utime + ua[0].u_stime + 30)/60; printf(" %2ld:", tm/60); tm =% 60; printf(tm<10?"0%ld":"%ld", tm); if(mproc[0].p_pid == 0){ printf(" Scheduler\n"); return(NONEWLINE); } c = mproc[0].p_size - 8; oc = c; oc =<< 6; o =+ oc; lseek(mf, o, 0); if (read(mf, ua, 512) != 512) return(NEWLINE); for (ip = &ua[256]; ip > &ua[0];) { if (*--ip == -1) { cp = ip+1; if (*cp==0) cp++; nbad = 0; for (cp1 = cp; cp1 < &ua[256]; cp1++) { c = *cp1; if (c==0) *cp1 = ' '; else if (c < ' ' || c > 0176) { if (++nbad >= 5) { *cp1++ = ' '; break; } *cp1 = '?'; } } while (*--cp1==' ') *cp1 = 0; printf(lflg?" %.30s":" %.60s", cp); return(NEWLINE); } } return(NEWLINE); } gettty() { register i; int q; q.lobyte = '?'; q.hibyte = ' '; if (ua[0].u_ttyp==0){ return(q); } for (i=0; i1 && *argv[1]=='-') { llen = 100; ptflg++; argc--; argv++; } if(argc<2) { printf("arg count\n"); exit(1); } fin = open(argv[1]); if(fin < 0) { printf("%s: cannot open\n", argv[1]); exit(1); } f = creat(tfil, 0600); if(f < 0) { printf("cannot create %s\n", tfil); exit(1); } fout = f; if ((signal(2, 1) & 01) ==0) signal(2, onintr); pass1(); flush(); close(fin); fin = 0; close(fout); fout = 1; f = fork(); if(f < 0) { printf("try again\n"); exit(1); } if(f == 0) { execl("/bin/sort", "sort", "-d", "-o", tfil, tfil, 0); execl("/usr/bin/sort", "sort", "-d", "-o", tfil, tfil, 0); printf("someone moved sort\n");  exit(1); } while(wait(0) != f); fin = open(tfil, 0); if(fin < 0) { printf("cannot reopen %s\n", tfil); exit(1); } if (argc>=3) f = creat(argv[2], 0666); else f = dup(1); if(f < 0) { printf("%s: cannot open\n", argv[2]); exit(1); } fout = f; pass2(); flush(); onintr(); } onintr() { unlink(tfil); exit(0); } pass1() { int n, c, i, ll, j, k, cc, ccc; loop: if ((c=getchar())=='\0') return; n = 0; i = 0; while(c!='\n' && c!='\0') { if(c == '(') c = 0177; if(c==' ' || c=='\t') { i++; c = getchar(); continue; } if(i) { i = 0; if(n<=llen) line[n++] = ' '; } if (n<=llen) line[n++] = c; c = getchar(); } ll = n; line[n++] = 0; i = -1; l1: while((cc=line[++i])==' '); n = i; j = 0; while(sw[j]) { i = n; k = 0; while ((cc=sw[j][k++])==line[i++]); if(cc==0 && ((ccc=line[--i])==' '||ccc==0)) goto l1; j++; } i = n; while (c=line[n++]) putchar(c); putchar('~'); n = 0; while (n=0) nafter++; else nbfore++; n++; c = getchar(); } if (tilde<0) tilde = n++; nafter--; if (nbfore>llen2) { i = tilde; while (nbfore > llen2) while(line[--i]!=' ' && i>=0) nbfore--; if (i<0) goto l1; line[tilde] = 0200; nafter =+ (tilde-i+2); tilde = i; } if (nafter >= llen-llen2) { i = tilde; while(nafter-- >= llen-llen2) while(line[++i]!=' ' && i=n) goto l1; line[tilde] = 0200; nafter++; tilde = i; } l1: if(!ptflg) { for(i=llen-llen2-nafter; i>=8; i =- 8) putchar('\t'); while(--i>=0) putchar(' '); } else printf(".xx \""); i = tilde; while (++i=n) goto l1; line[tilde] = 0200; nafter++; tilde = i; } l1: if(!ptflg) { for(i=llen-llen2-nafter; i>=8; i =- 8) putchar('\t'); while(--i>=0) putchar(' '); } else printf(".xx \""); i = tilde; while (++i 511) prname(); for(j=off+1; j>=0; --j) name[j+i+1] = name[j]; off=i+off+1; name[i] = '/'; for(--i; i>=0; --i) name[i] = str[i]; } mtab.file[0] == '/' && mtab.file[1] == 0) cat(""); else cat(mtab.file); break; } } while (read(file/* * relocate command-- * reloc file [-]octal [ - ] * * relocate object or a.out file up in core * by the possibly negated octal number. * * if optional 3rd arg is given, * replace "setd" at start by "nop" */ int tbuf[256]; int rbuf[256]; int fin; int fout; int *txtp; int *relp; int relloc; int txtloc; int dotdot; int txtsiz; int t1; int t2; int t4; int t7; int txtw; main(argc, argv) char *argv[]; { int sign, c; if (argc<3) { usage: write(1, "reloc file [-]octal\n", 20); return; } dotdot = 0; if (*argv[2] == '-') { sign = -1; argv[2]++; } else sign = 1; while (*argv[2]) { c = *argv[2]++ - '0'; if (c<0 || c>7) goto usage; dotdot = (dotdot<<3) + c; } dotdot =* sign; if ((fin = open(argv[1], 0)) < 0) { write(1, "File not readable\n", 18); return; } if ((fout = open(argv[1], 1)) < 0) { write(1, "File not writable\n", 18); return; } txtw = read(fin, tbuf, 512); if (tbuf[0]!=0410 && tbuf[0]!=0407) { /* magic */ write(1, "Bad format\n", 11); return; } if (tbuf[7] != 0) { /* relocation? */ write (1, "No relocation bits\n", 19); return; } t1 = tbuf[1]; t2 = tbuf[2]; t4 = tbuf[4]; txtloc = 020; if (argc>3 && argv[3][1]=='o') { dotdot =+ 020; tbuf[0] = 0405; /* old magic */ tbuf[1] =+ tbuf[2]; tbuf[2] = 0; tbuf[4] = tbuf[3]; tbuf[3] = 0; tbuf[6] = 0240; tbuf[7] = t7 = 0240; } txtsiz = tbuf[1]+tbuf[2]; relloc = txtloc+txtsiz; txtsiz = (txtsiz>>1) & 077777; seek(fin, relloc&~0777, 0); read(fin, rbuf, 512); txtp = &tbuf[8]; relp = &rbuf[(relloc&0777) >> 1]; if (argc>3) /* nop out "setd" at start */ if (tbuf[8] == 0170011) tbuf[8] = 0240; while(txtsiz--) { switch (*relp & 017) { case 01: /* pc ref to abs */ *txtp =- dotdot; break; case 02: /* ref to text */ case 04: /* ref to data */ case 06: /* ref to bss */ *txtp =+ dotdot; } advance(); } if (txtp != &tbuf[0]) write(fout, &tbuf[0], txtw); txtsiz = (t4 >> 1) & 077777; relloc = 020 + 2*(t1 + t2); seek(fin, relloc&~0777, 0); seek(fout, relloc&~0777, 0); txtw = read(fin, tbuf, 512); txtp = &tbuf[(relloc&0777) >> 1] + 4; while((txtsiz =- 6) > 0) { switch(*txtp & 77) { case 2: case 3: case 4: *(txtp + 1) =+ dotdot; } adv6(); } if(txtp != &tbuf[0]) write(fout, &tbuf[0], txtw); } advance() { relp++; relloc =+ 2; if (relp == &rbuf[256]) { seek(fin, relloc, 0); read(fin, &rbuf[0], 512); relp = &rbuf[0]; } txtp++; txtloc =+ 2; if (txtp >= &tbuf[256]) { write(fout, &tbuf[0], txtw); seek(fin, txtloc, 0); txtw = read(fin, &tbuf[0], 512); txtp = &tbuf[0]; } } adv6() { txtp =+ 6; if(txtp >= &tbuf[256]) { write(fout, tbuf, txtw); txtw = read(fin, tbuf, 512); txtp =- 256; } } + dotdot; } adv6(); } if(txtp != &tbuf[0]) write(fout, &tbuf[0], txtw); } advance() { relp++; relloc =+ 2; if (relp == &rbuf[256]) { seek(fin, relloc, 0); read(fin, &rbuf[0], 512); relp = &rbuf[0]; } txtp++; txtloc =+ 2; if (txtp >= &tbuf[256]) { write(fout, &tbuf[0], txtw); seek(fin, txtloc, 0); # /* * restore from incremental dumps */ char *dargv[] { 0, "t", 0 }; char *ifile "/dev/rmt0"; char *ifile1 "/dev/rmt2"; char *ofile; #include "../head/ino.h" #include "../head/filsys.h" struct filsys sblock; int isize; int *talist; int bufsiz; int fi; int *bigbuf; int buf[256]; int dbuf[256]; int cbuf[256]; char *date[2]; char *ddate[2]; int fo; int pher; char *tsize; int recsiz; int iflg; int wflg; int cflg; char file[10]; int ilist[100]; main(argc, argv) char **argv; { char *key; register *tap, *p; register struct inode *ip; int i, com, sz, *q, l; if(argc == 1) { argv = dargv; for(argc = 1; dargv[argc]; argc++); } argc--; argv++; key = *argv; while(*key) switch(*key++) { default: printf("bad character in key\n"); exit(0); case 't': case 'r': case 'x': com = key[-1]; continue; case 'i': iflg++; continue; case '-': continue; case 'c': cflg++; continue; case 'f': argv++; argc--; ifile = *argv; continue; case 'w': wflg++; continue; case 'q': ifile = ifile1; continue; } otape(1); i = read(fi,buf,512); if(i != 512){ printf("Read error in super-block ! Is tape drive key set ?\n"); } i = 0; tap = buf; for(l = 0;l < 256;l++) i =+ *tap++; if(i != 031415){ printf("Checksum error in the super-block !\n"); if(!iflg) exit(0); } close(fi); otape(0); tap = buf; isize = *tap++; *tap++; /* fsize */ date[0] = *tap++; date[1] = *tap++; ddate[0] = *tap++; ddate[1] = *tap++; tsize = *tap++; recsiz = *tap++; if(recsiz == 0) recsiz = 1; printf("The record size of this tape = %d blocks\n",recsiz); bufsiz = recsiz*512; bigbuf = sbrk(bufsiz); if(bigbuf == -1){ printf("No memory !\n"); exit(0); } rawin(1,0,1); sread(buf, 0); i = size(0, isize*32); talist = sbrk(i*512); if(talist == -1){ printf("NO memory !\n"); exit(0); } tap = talist; while(i--) { tread(tap, 0); tap =+ 256; } switch(com) { case 't': l = 0; com = 0; pdate(ddate); pdate(date); tap = talist; for(i=0; i 60) { printf("\n"); l = 0; } else printf(","); com = 0; } else if(com == 0) com = i+1; } if(com) printf("%l-\n", com); printf("\n"); exit(0); case 'r': if(argc <= 1) { printf("no filesystem name\n"); exit(0); } ofile = argv[1]; fo = open(ofile, 2); if(fo < 0) { printf("can not open %s\n", ofile); exit(0); } printf("last chance before scribbling on %s\n", ofile); rdline(); dread(1, &sblock); tap = talist; for(i=0; i= isize) break; dread(i+2, buf); for(ip = &buf[0]; ip < &buf[256]; ip++) { sz = *tap++; if(sz == 0) continue; dealoc(ip); if(sz == -1) { for(p = ip; p < &ip->i_mtime[2]; ) *p++ = 0; continue; } sread(dbuf, 0); q = dbuf; for(p = ip; p < &ip->i_mtime[2]; ) *p++ = *q++; restor(ip, sz-1); } dwrite(i+2, buf); } dwrite(1, &sblock); com = 0; for(; i < isize; i++) for(l = 0; l < 16; l++) { sz = *tap++; if(sz != 0 && sz != -1) com++; } if(com) printf("%l files not restored - small ilist\n", com); exit(0); case 'x': i = 0; tap = ilist; while(argc > 1) { i++; sz = number(argv[1]); argv++; argc--; if(sz <= 0 || sz >=isize*16) { printf("%l not in range\n", sz); continue; } if(talist[sz-1] == 0) { printf("%l not dumped\n", sz); continue; }  if(talist[sz-1] == -1) { printf("%l does not exist\n", sz); continue; } *tap++ = sz; } if(i != 0 && ilist[0] == 0) exit(0); tap = talist; for(i=1; i<=isize*16; i++) { if(ilist[0] != 0) { for(sz=0; ilist[sz]; sz++) if(ilist[sz] == i) goto yes; sz = *tap++; no: if(sz == -1) sz = 0; while(sz--) tread(dbuf, 1); continue; } yes: sz = *tap++; if(sz == 0 || sz == -1) continue; fo = dwait(i); if(fo < 0) goto no; sz--; sread(buf, 0); ip = buf; while(sz--) { tread(dbuf, 0); com = 512; if(ip->i_size0 == 0 && ip->i_size1 < 512) com = ip->i_size1; write(fo, dbuf, com); if(com > ip->i_size1) ip->i_size0--; ip->i_size1 =- com; } close(fo); chmod(file, ip->i_mode); chown(file, ip->i_uid); } exit(0); } } dealoc(p) struct inode *p; { register struct inode *ip; register i, j; int k; int xbuf[256], ybuf[256]; ip = p; if(ip->i_mode & (IFCHR&IFBLK)) return; for(i=7; i>=0; i--) if(ip->i_addr[i]) { if(ip->i_mode&ILARG) { dread(ip->i_addr[i], xbuf); for(j=255; j>=0; j--) if(xbuf[j]) { /* this section for huge files */ /*if(i == 7) { dread(xbuf[j], ybuf); for(k=255; k>=0; k--) if(ybuf[k]) free(ybuf[k]); }*/ free(xbuf[j]); } } free(ip->i_addr[i]); } } restor(p, sz) struct inode *p; { register struct inode *ip; register i, j; int xbuf[256]; ip = p; if(ip->i_mode & (IFCHR&IFBLK)) return; for(i=0; i<8; i++) ip->i_addr[i] = 0; if(sz <= 8) { for(i=0; ii_addr[i] = rcop(); ip->i_mode =& ~ILARG; return; } for(i=0; i<256; i++) xbuf[i] = 0; for(j=0; sz >= 256; j++) { /*if(j <= 7) huge*/ ip->i_addr[j] = alloc(); /*if(j >= 7) huge*/ /*xbuf[j-7] = alloc(); huge*/ for(i=0; i<256; i++) dbuf[i] = rcop(); /*if(j < 7) huge*/ dwrite(ip->i_addr[j], dbuf); /*else dwrite(xbuf[j-7], dbuf); huge*/ sz =- 256; } if(sz) { /*if(j <= 7) huge*/ ip->i_addr[j] = alloc(); /*if(j >= 7) huge*/ /*xbuf[j-7] = alloc(); huge*/ for(i=0; ii_addr[j], dbuf); /*else dwrite(xbuf[j-7], dbuf); huge*/ } /*if(j >= 7) huge*/ /*dwrite(ip->i_addr[7], xbuf); huge*/ ip->i_mode =| ILARG; } rcop() { register b; b = alloc(); tread(cbuf, 0); dwrite(b, cbuf); return(b); } pdate(d) int *d; { if(d[0] == 0 && d[1] == 0) printf("the epoch\n"); else printf(ctime(d)); } dread(bno, b) { seek(fo, bno, 3); if(read(fo, b, 512) != 512) { printf("disk read error %l\n", bno); exit(0); } } dwrite(bno, b) { seek(fo, bno, 3); if(write(fo, b, 512) != 512) { printf("disk write error %l\n", bno); exit(0); } } sread(b, flag) int *b; { register i, s, *p; tread(b, flag); if(flag) return; i = 256; s = 0; p = b; while(i--) s =+ *p++; if(s != 031415) { printf("checksum error\n"); if(!iflg) exit(0); } } tread(b, flag) int *b; { register c; static char *pta, *ctflg, *ntape; static int tapeno; int *p, pt; if(pta++ >= recsiz) { pta = 1; ctflg++; ntape++; if(ntape == tsize){ ctflg = 1; ntape = 1; tapeno++; } } if(flag) return; if(ctflg) { rawin(ctflg,tapeno,ntape); ctflg = 0; tapeno = 0; } pt = pta; p = bigbuf + (pt - 1)*256; for(pt = 0;pt < 256;pt++) *b++ = *p++; } rawin(ctflg,tapeno,ntape) char *ctflg; { register *b, i; int c; if(tapeno){ printf("change tapes\n"); if(tapeno > 1) printf("skip %d tapes\n",tapeno-1); close(fi); if (!cflg) rdline(); otape(0); } for(i = ctflg-1;i > 0;i--){ if(read(fi, bigbuf, bufsiz) != bufsiz) printf("read error at record %l\n",ntape); } if(read(fi, bigbuf, bufsiz) != bufsiz) { printf("read error at record %l\n",ntape); if(!iflg) exit(0); } } number(s) char *s; { register n, c; n = 0; while(c = *s++) { if(c<'0' || c>'9') continue; n = n*10+c-'0'; } return(n); } size(s0, s1) { register s; extern ldivr; s = ldiv(s0&0377, s1, 512); if(ldivr) s++; return(s); } otape(flg) { register char *p; while(( fi = open(ifile, 0)) < 0){ printf("can not open %s\n", ifile); rdline(); } if(!cflg || flg) return; p = ifile; while(*p++) ; p[-2]++; } rdline() { char c; while(read(0,&c,1) != '\0'){ if(c == '\n') return; } exit(0); } dwait(ino) { register i, yflg; dconv(ino, file); if(wflg){ printf("%s ",file); while((i = getchar()) != '\n'){ if(i == 'y') yflg++; if(i == 'x') exit(0); } if(yflg) return(creat(file, 0666)); else return(-1); } return(creat(file, 0666)); } dconv(n, p) char *p; { register i; if(i = ldiv(0, n, 10)) p = dconv(i, p); *p++ = lrem(0, n, 10) + '0'; *p = '\0'; return(p); } alloc() { register b, i; i = --sblock.s_nfree; if(i<0 || i>=100) { printf("bad freeblock\n"); exit(0); } b = sblock.s_free[i]; if(b == 0) { printf("out of freelist\n"); exit(0); } if(sblock.s_nfree <= 0) { dread(b, cbuf); sblock.s_nfree = cbuf[0]; for(i=0; i<100; i++) sblock.s_free[i] = cbuf[i+1]; } return(b); } free(in) { register i; if(sblock.s_nfree >= 100) { cbuf[0] = sblock.s_nfree; for(i=0; i<100; i++) cbuf[i+1] = sblock.s_free[i]; sblock.s_nfree = 0; dwrite(in, cbuf); } sblock.s_free[sblock.s_nfree++] = in; } <0 || i>=100) { printf("bad freeblock\n"); exit(0); } b = sblock.s_free[i]; if(b == 0) { printf("out of freelist\n"); exit(0); } if(sblock.s_nfree <= 0) { dread(b, cbuf); sblock.s_nfree = cbuf[0]; for(i=0; i<100; i++) sblock.s_free[i] = cbuf[i+1]; } return(b)/ rew -- rewind dec/mag tape cmp (sp)+,$2 blt 1f tst (sp)+ mov (sp)+,r0 movb (r0)+,r1 cmp r1,$'m beq rewm movb r1,tapx+8 tstb (r0) bne error 1: sys open; tapx; 0 br rew rewm: movb (r0)+,r1 beq 1f movb r1,mtx+7 tstb (r0) bne error 1: sys open; mtx; 0 rew: bes error sys read; word; 2 bes error sys exit error: mov $1,r0 sys write; 0f; 2 sys exit 0: tapx: mtx: .even .bss word: .=.+2 0; i<100; i++) sblock.s_free[i] = cbuf[i+1]; } return(b)# /* * status codes */ /* Overall status */ #define ALLGOOD 0 #define SOMEBAD 4 #define ALLBAD -1 /* Incremental status */ #define GOOD 0 #define BAD 4 #define VBAD -1 struct xcode{ int summary; int count; }xcode; main(argc, argv) char *argv[]; { char *arg; int fflg, rflg, ex; xcode.summary = ALLGOOD; xcode.count = argc - 1; fflg = 0; rflg = 0; while(--argc > 0) { arg = *++argv; if(arg[0] == '-') { xcode.count--; if(arg[1] == 'f') { fflg++; continue; } if(arg[1] == 'r') { rflg++; continue; } } if((ex = rm(arg, fflg, rflg)) > GOOD) { xcode.count--; if(ex > xcode.summary) { xcode.summary = ex; } } } if(xcode.count == 0) exit(ALLBAD); else exit(xcode.summary); } struct stbuf { int dev; int inum; int mode; char nlink; char uid; char gid; char siz0; char siz1; int addr[8]; int adate[2]; int mdate[2]; }; rm(arg, fflg, rflg) char arg[]; { char *p; int buf[20]; int i, b; int status; int ln; struct{ char lobyte; char hibyte; }; if(stat(arg, buf)) { printf("%s: non existent\n", arg); return(BAD); } if((buf->mode & 060000) == 040000) { if(rflg) { i = fork(); if(i == -1) { printf("%s: try again\n", arg); return(VBAD); } if(i) { while(wait(&status) != i); return(status >> 8); } if(chdir(arg)) { printf("%s: cannot chdir\n", arg); exit(BAD);; } p = 0; execl("/etc/glob", "glob", "rm", "-r", fflg? "-f": "*", fflg? "*": p, 0); printf("%s: no glob\n", arg); exit(VBAD); } printf("%s: directory\n", arg); return(BAD); } if(!fflg) { if((getuid()&0377) == buf->uid) b = 0200; else b = 2; ln = lnxx(0); if((buf->mode & b)==0 && (ln.lobyte!='x' || ln.hibyte!='x')){ printf("%s: %o mode ", arg, buf->mode); i = b = getchar(); i = b; while(b != '\n' && b != '\0') b = getchar(); if(i != 'y') return(GOOD); } } if(unlink(arg)) { printf("%s: not removed\n", arg); return(BAD); } return(GOOD); } putchar(c) { write(1, &c, 1); } getchar() { char c; if(read(0, &c, 1) != 1) return(0); return(c); } ) { if((getuid()&0377) == buf->uid) b = 0200; else b = 2; ln = lnxx(0); if((buf->mode & b)==0 && (ln.lobyte!='x' || ln.hibyte!='x')){ printf("%s: %o mode ", arg, buf->mode); i = b = getchar(); i = b; while(b != '\n' && b != '\0') b = getchar(); if(i != 'y') return(GOOD); } } if(unlink(arg)) { printf("%s: not removed\n", arg); return(BAD); } return(GOOD); } putchar(c) { writ/ rmdir -- unlink directory mov (sp)+,r5 tst (sp)+ loop: dec r5 ble done mov (sp)+,r1 mov $name,r2 clr r0 1: inc r0 movb (r1)+,(r2)+ bne 1b dec r2 dec r0 mov r0,size cmp r2,$name beq error sys stat; name; stbuf bes error bic $!60000,stbuf+4 cmp $40000,stbuf+4 bne error cmpb -1(r2),$'. bne 1f cmp r2,$name+1 beq error cmpb -2(r2),$'/ beq error cmpb -2(r2),$'. bne 1f cmp r2,$name+2 beq error cmpb -3(r2),$'/ beq error 1: sys open; name; 0 bes error mov r0,r1 1: mov r1,r0 sys read; stbuf; 16. bes 1f tst r0 beq 1f tst stbuf beq 1b cmpb stbuf+2,$'. bne error1 tstb stbuf+3 beq 1b cmpb stbuf+3,$'. bne error1 tstb stbuf+4 beq 1b error1: jsr pc,prname mov r1,r0 sys close mov $1,r0 sys write; mes1; emes1-mes1 br loop 1: mov r1,r0 sys close movb $'/,(r2)+ movb $'.,(r2)+ movb $'.,(r2)+ clrb (r2) sys unlink; name clrb -(r2) sys unlink; name clrb -2(r2) sys unlink; name br loop error: jsr pc,prname mov $1,r0 sys write; mes2; emes2-mes2 br loop prname: mov $1,r0 sys write; name; size:.. rts pc done: sys exit mes1: < -- directory not empty\n> emes1: mes2: < ?\n> emes2: .even .bss name: .=.+40. stbuf: .=.+40. 1: jsr pc,prname mov r1,r0 sys close mov $1,r0 sys write; mes1; emes1-mes1 br loop 1: mov r1,r0 sys close movb $'/,(r2)+ movb $'.,(r2)+ movb $'.,(r2)+ clrb (r2) sys unlink; name clrb -(r2) sys unlink; name clrb -2(r2) sys unlink; name br loop error: jsr pc,prname mov $1,r0 sys write; mes2; emes2-mes2 br loop prna# /* interpret command time accounting */ #define size 1000 #define BXEC 1 int lflg; int cflg; int iflg; int jflg; int nflg; int aflg; int rflg; int oflg; int tflg; int vflg; int uflg; int thres 1; int sflg; int bflg; int mflg; int fout; struct user { int ncomm; int fill; float fctime; } user[256]; struct tab { char name[14]; int count; float realt; float cput; float syst; } tab[size]; struct ftab { char fname[14]; char shf; char uid; long fdatet; long frealt; long fcput; long fsyst; }; float treal; float tcpu; float tsys; int junkp -1; char *sname; float ncom; main(argc, argv) char **argv; { int i, j, k; extern tcmp(), ncmp(), bcmp(); extern float sum(); float ft; if (argc>1) if (argv[1][0]=='-') { argv++; argc--; for(i=1; argv[0][i]; i++) switch(argv[0][i]) { case 'o': oflg++; break; case 'i': iflg++; break; case 'b': bflg++; break; case 'l': lflg++; break; case 'c': cflg++; break; case 'j': jflg++; break; case 'n': nflg++; break; case 'a': aflg++; break; case 'r': rflg++; break; case 't': tflg++; break; case 's': sflg++; aflg++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': thres = argv[0][i]-'0'; break; case 'v': vflg++; break; case 'u': uflg++; break; case 'm': mflg++; break; } } fout = dup(1); if (iflg==0) init(); if (argc<2) doacct("/usr/adm/acct"); else while (--argc) doacct(*++argv); if (uflg || ncom < 1. || treal+tcpu+tsys < 1.) { flush(); exit(0); } /* * cleanup pass * put junk together */ if (vflg) strip(); if(!aflg) for (i=0; i= 0) { write(i, user, sizeof(user)); close(i); } else { printf("Can't save usracct\n"); } if ((i = creat("/usr/adm/savacct", 0666)) < 0) { printf("Can't save savacct\n"); flush(); exit(0); } write(i, tab, k*sizeof(tab[0])); close(i); signal(2, 0); } /* * sort and print */ if (mflg) { printmoney(); flush(); exit(0); } qsort(tab, k, sizeof(tab[0]), nflg? &ncmp: (bflg?&bcmp:&tcmp)); column(ncom, treal, tcpu, tsys); printf("\n"); for (i=0; i= 0200)) { *cp = '?'; } } if (fbuf.shf&BXEC) { for (cp=fbuf.fname; cp < &fbuf.fname[14]; cp++) if (*cp==0) { *cp = '*'; break; } } if(fbuf.frealt < 0) fbuf.frealt = 0; if (uflg) { printdate(&fbuf.fdatet); printf(" %3d %.14s\n", fbuf.uid&0377, fbuf.name); continue; } c = fbuf.uid&0377; user[c].ncomm++; user[c].fctime =+ (fbuf.fcput+fbuf.fsyst)/60.; ncom =+ 1.0; i = enter(&fbuf); tab[i].count++; x = fbuf.frealt*60; tab[i].realt =+ x; treal =+ x; tab[i].cput =+ fbuf.fcput; tcpu =+ fbuf.fcput; tab[i].syst =+ fbuf.fsyst; tsys =+ fbuf.fsyst; } close(ff); } ncmp(p1, p2) struct tab *p1, *p2; { if(p1->count == p2->count) return(tcmp(p1, p2)); if(rflg) return(p1->count - p2->count); return(p2->count - p1->count); } bcmp(p1, p2) struct tab *p1, *p2; { float f1, f2; float sum(); f1 = sum(p1)/p1->count; f2 = sum(p2)/p2->count; if(f1 < f2) { if(rflg) return(-1); return(1); } if(f1 > f2) { if(rflg) return(1); return(-1); } return(0); } tcmp(p1, p2) struct tab *p1, *p2; { extern float sum(); float f1, f2; f1 = sum(p1); f2 = sum(p2); if(f1 < f2) { if(rflg) return(-1); return(1); } if(f1 > f2) { if(rflg) return(1); return(-1); } return(0); } float sum(p) struct tab *p; { if(p->name[0] == 0) return(0.0); return( p->cput+ p->syst); } init() { struct tab tbuf; int i, j, f; if ((f=open("/usr/adm/savacct", 0))<0) goto gshm; while (read(f, &tbuf, sizeof(tbuf)) == sizeof(tbuf)) { i = enter(&tbuf); ncom =+ tbuf.count; tab[i].count = tbuf.count; treal =+ tbuf.realt; tab[i].realt = tbuf.realt; tcpu =+ tbuf.cput; tab[i].cput = tbuf.cput; tsys =+ tbuf.syst; tab[i].syst = tbuf.syst; } close(f); gshm: if ((f = open("/usr/adm/usracct", 0)) < 0) return; read(f, user, sizeof(user)); close(f); } enter(fbuf) struct ftab *fbuf; { int i, j; for (i=j=0; i<14; i++) { if (fbuf->fname[i]==0) j = i; if (j) fbuf->fname[i] = 0; } for (i=j=0; j<14; j++) { i = i*7 + fbuf->fname[j]; } if (i < 0) i = -i; for (i=%size; tab[i].name[0]; i = (i+1)%size) { for (j=0; j<14; j++) if (tab[i].name[j]!=fbuf->fname[j]) goto no; goto yes; no:; } for (j=0; j<14; j++) tab[i].name[j] = fbuf->fname[j]; yes: return(i); } strip() { int i, j, k, c; j = enter("**junk**"); for (i = 0; iad1 = respace; lbend = &linebuf[LBSIZE]; ptrend = &ptrspace[PTRSIZE]; reend = &respace[RESIZE]; labend = &labtab[LABSIZE]; lnum = 0; pending = 0; depth = 0; spend = linebuf; while (--eargc > 0 && (++eargv)[0][0]=='-') switch (eargv[0][1]) { case 'n': nflag++; continue; case 'f': close(fin); if(eargc-- <= 0) exit(2); if((fin = open(*++eargv, 0)) < 0) { printf2("Cannot open pattern-file: %s\n", *eargv); exit(2); } fcomp(); close(fin); continue; case 'e': eflag++; fcomp(); eflag = 0; continue; case 'g': gflag++; continue; default: printf("Unknown flag: %c\n", eargv[0][1]); continue; } if(rep == ptrspace) {  eargv--; eargc++; eflag++; fcomp(); eargv++; eargc--; eflag = 0; } if(depth) printf2("Too many {'s"); labtab->address = rep; dechain(); /* abort(); /*DEBUG*/ if(eargc <= 0) execute(0); else while(--eargc >=0) { execute(*eargv++); } flush(); exit(0); } fcomp() { register char *p, *op, *tp; struct reptr *pt, *pt1; int i; struct label *lpt; op = lastre; if(rline(linebuf) <0) return(0); if(*linebuf == '#' && linebuf[1] == 'n') nflag = 1; else { cp = linebuf; goto comploop; } for(;;) { if(rline(linebuf) < 0) break; cp = linebuf; comploop: /* printf("cp: %s\n", cp); /*DEBUG*/ while(*cp == ' ' || *cp == '\t') cp++; if(*cp == '\0') continue; p = address(rep->ad1); if(p == -1) printf2(CGMES); if(p == rep->ad1) { if(op) rep->ad1 = op; else printf2("First RE may not be null\n"); } else if(p == 0) { p = rep->ad1; rep->ad1 = 0; } else { op = rep->ad1; if(*cp == ',' || *cp == ';') { cp++; if((rep->ad2 = p) > reend) printf2(TMMES); p = address(rep->ad2); if(p == -1 || p == 0) printf2(CGMES); if(p == rep->ad2) rep->ad2 = op; else op = rep->ad2; } else rep->ad2 = 0; } if(p > reend) printf2("Too much text: %s\n", linebuf); gvloop: switch(*cp++) { default: printf2("Unrecognized command: %s\n", linebuf); case '{': rep->command =| JCOM; rep->re1 = rep + 2; if(++rep >= ptrend) printf2("Too many commands\n"); rep->ad1 = 0; rep->command = JCOM; cmpend[depth++] = &rep->re1; if(++rep >= ptrend) printf2("Too many commands\n"); rep->ad1 = p; if(*cp == '\0') continue; goto comploop; case '}': if(rep->ad1) printf2(AD0MES); if(--depth < 0) printf2("Too many }'s\n"); *cmpend[depth] = rep; rep->ad1 = p; continue; case '=': rep->command =| EQCOM; if(rep->ad2) printf2(AD1MES); break; case ':': if(rep->ad1) printf2(AD0MES); while(*cp++ == ' '); cp--;  tp = lab->asc; while((*tp++ = *cp++)) if(tp >= &(lab->asc[8])) printf2(LTL); *--tp = '\0'; if(lpt = search(lab)) { if(lpt->address) printf2("Duplicate labels: %s\n", linebuf); } else { lab->chain = 0; lpt = lab; if(++lab >= labend) printf2("Too many labels: %s\n", linebuf); } lpt->address = rep; rep->ad1 = p; continue; case 'a': rep->command =| ACOM; if(rep->ad2) printf2(AD1MES); if(*cp == '\\') cp++; if(*cp++ != ('\n')) printf2(CGMES); rep->re1 = p; p = text(rep->re1); break; case 'c': rep->command =| CCOM; if(*cp == '\\') cp++; if(*cp++ != ('\n')) printf2(CGMES); rep->re1 = p; p = text(rep->re1); break; case 'i': rep->command =| ICOM; if(rep->ad2) printf2(AD1MES); if(*cp == '\\') cp++; if(*cp++ != ('\n')) printf2(CGMES); rep->re1 = p; p = text(rep->re1); break; case 't': rep->command =| TCOM; goto jtcommon; case 'j': rep->command =| JCOM; jtcommon: while(*cp++ == ' '); cp--; if(*cp == '\0') { if(pt = labtab->chain) { while(pt1 = pt->re1) pt = pt1; pt->re1 = rep; } else labtab->chain = rep; break; } tp = lab->asc; while((*tp++ = *cp++)) if(tp >= &(lab->asc[8])) printf2(LTL); cp--; *--tp = '\0'; if(lpt = search(lab)) { if(lpt->address) { rep->re1 = lpt->address; } else { pt = lpt->chain; while(pt1 = pt->re1) pt = pt1; pt->re1 = rep; } } else { lab->chain = rep; lab->address = 0; if(++lab >= labend) printf2("Too many labels: %s\n", linebuf); } break; case 'n': rep->command =| NCOM; break; case 'N': rep->command =| CNCOM; break; case 'p': rep->command =| PCOM; break; case 'P': rep->command =| CPCOM; break; case 'r': rep->command =| RCOM; if(rep->ad2) printf2(AD1MES);  if(*cp++ != ' ') printf2(CGMES); rep->re1 = p; p = text(rep->re1); break; case 'd': rep->command =| DCOM; break; case 'D': rep->command =| CDCOM; rep->re1 = ptrspace; break; case 'q': rep->command =| QCOM; if(rep->ad2) printf2(AD1MES); break; case 'l': rep->command =| LCOM; break; case 's': rep->command =| SCOM; seof = *cp++; rep->re1 = p; p = compile(rep->re1); if(p == -1) printf2(CGMES); if(p == rep->re1) { rep->re1 = op; } else { op = rep->re1; } if(snlf) rep->nlf = 1; if((rep->rhs = p) > reend) printf2(TMMES); if((p = compsub(rep->rhs)) == -1) printf2(CGMES); break; case 'w': rep->command =| WCOM; if(*cp++ != ' ') printf2(CGMES); if(nfiles >= 10) printf2("Too many files in w commands\n"); text(fname[nfiles]); for(i = nfiles - 1; i >= 0; i--) if(cmp(fname[nfiles], fname[i]) == 0) { rep->fcode = fcode[i];  goto done; } if((rep->fcode = creat(fname[nfiles],0777)) < 0) printf2("Cannot create %s\n", fname[nfiles]); fcode[nfiles++] = rep->fcode; break; case 'g': if(rep->command) printf2(CGMES); rep->command = GCOM; seof = *cp++; rep->re2 = p; p = compile(rep->re2); if(p == -1) printf2(CGMES); if(p == rep->re2) { rep->re2 = op; } else { op = rep->re2; } if(p > reend) printf2(TMMES); goto gvloop; case 'v': if(rep->command) printf2(CGMES); rep->command = VCOM; seof = *cp++; rep->re2 = p; p = compile(rep->re2); if(p == -1) printf2(CGMES); if(p == rep->re2) { rep->re2 = op; } else { op = rep->re2; } if(p > reend) printf2(TMMES); goto gvloop; } if(*cp == 'g') { cp++; rep->gfl++; } else if(gflag) rep->gfl++; if(*cp == 'p') { cp++; rep->pfl = 1; } if(*cp == 'P') { cp++; rep->pfl = 2; } if(*cp == 'w') { cp++; if(*cp++ != ' ') printf2(CGMES); if(nfiles >= 10) printf2("Too many files in w commands\n"); text(fname[nfiles]); for(i = nfiles - 1; i >= 0; i--) if(cmp(fname[nfiles],fname[i]) == 0) { rep->fcode = fcode[i]; goto done; } if((rep->fcode=creat(fname[nfiles],0777)) < 0) printf2("cannot open %s\n", fname[nfiles]); fcode[nfiles++] = rep->fcode; } done: if(++rep >= ptrend) printf2("Too many commands, last: %s\n", linebuf); rep->ad1 = p;  if(*cp++ != '\0') printf2(CGMES); } rep->command = 0; lastre = op; } compsub(rhsbuf) char *rhsbuf; { register char *p, *q; p = rhsbuf; q = cp; for(;;) { if((*p = *q++) == '\\') { *p = *q++; if(*p > numbra + '0' && *p <= '9') return(-1); *p++ =| 0200; continue; } if(*p == seof) { *p++ = '\0'; cp = q; return(p); } if(*p++ == '\0') { return(-1); } } } printf2(s, a, b) { extern fout; flush(); fout = 2; printf(s, a, b); flush(); exit(2); } compile(expbuf) char *expbuf; { register c; register char *ep, *sp; char *lastep; int cclcnt; int closed; char bracket[NBRA], *bracketp; if(*cp == seof) { cp++; return(expbuf); } ep = expbuf; bracketp = bracket; closed = numbra = 0; snlf = 0; sp = cp; if (*sp == '^') { *ep++ = 1; sp++; } else { *ep++ = 0; } for (;;) { if (ep >= &expbuf[ESIZE]) { cp = sp; return(-1); } if((c = *sp++) == seof) { if(bracketp != bracket) { cp = sp; return(-1); } cp = sp; *ep++ = CEOF; return(ep); } if(c != '*') lastep = ep; switch (c) { case '\\': if((c = *sp++) == '(') { if(numbra >= NBRA) { cp = sp; return(-1); } *bracketp++ = numbra; *ep++ = CBRA; *ep++ = numbra++; continue; } if(c == ')') { if(bracketp <= bracket) { cp = sp; return(-1); } *ep++ = CKET; *ep++ = *--bracketp; closed++; continue; } if(c >= '1' && c <= '9') { if((c =- '1') >= closed) return(-1); *ep++ = CBACK; *ep++ = c; continue; } if(c == '\n') { cp = sp; return(-1); } if(c == 'n') { c = '\n'; } goto defchar; case '\0': continue; case '\n': cp = sp; return(-1); case '.': *ep++ = CDOT; continue; case '*': if (lastep==0) goto defchar; *lastep =| STAR; continue; case '$': if (*sp != seof) goto defchar; *ep++ = CDOL; continue; case '[': if(&ep[17] >= &expbuf[ESIZE]) printf2("RE too long: %s\n", linebuf);  *ep++ = CCL; if((c = *sp++) == '^') { for(cclcnt = 0; cclcnt < 16; cclcnt++) ep[cclcnt] = -1; ep[0] =& 0376; c = *sp++; } do { if(c == '\0') printf2(CGMES); if(c == '\\') { switch(c = *sp++) { case 'n': c = '\n'; break; } } ep[c >> 3] =^ bittab[c & 07]; } while((c = *sp++) != ']'); ep =+ 16; continue; defchar: default: *ep++ = CCHR; *ep++ = c; } } } rline(lbuf) { register char *p, *q; static saveq; p = lbuf - 1; if(eflag) { if(eflag > 0) { eflag = -1; if(eargc-- <= 0) exit(2); q = *++eargv; while(*++p = *q++) { if(*p == '\\') { if((*++p = *q++) == '\0') { saveq = 0; return(-1); } else continue; } if(*p == '\n') { *p = '\0'; saveq = q; return(1); } } saveq = 0; return(1); } if((q = saveq) == 0) return(-1); while(*++p = *q++) { if(*p == '\\') { if((*++p = *q++) == '0') { saveq = 0; return(-1);  } else continue; } if(*p == '\n') { *p = '\0'; saveq = q; return(1); } } saveq = 0; return(1); } while(*++p = getchar()) if(*p == '\\') *++p = getchar(); else if(*p == '\n') { *p = '\0'; return(1); } else if(*p == '\0') p--; return(-1); } address(expbuf) char *expbuf; { register char *rcp; long lno; if(*cp == '$') { cp++; *expbuf++ = CEND; *expbuf++ = CEOF; return(expbuf); } if(*cp == '/') { seof = '/'; cp++; return(compile(expbuf)); } rcp = cp; lno = 0; while(*rcp >= '0' && *rcp <= '9') lno = lno*10 + *rcp++ - '0'; if(rcp > cp) { *expbuf++ = CLNUM; *expbuf++ = nlno; tlno[nlno++] = lno; if(nlno >= NLINES) printf2("Too many line numbers\n"); *expbuf++ = CEOF; cp = rcp; return(expbuf); } return(0); } cmp(a, b) char *a,*b; { register char *ra, *rb; ra = a - 1; rb = b - 1; while(*++ra == *++rb) if(*ra == '\0') return(0); return(1); } text(textbuf) char *textbuf; { register char *p, *q; p = textbuf; q = cp; for(;;) { if((*p = *q++) == '\\') { *p++ = *q++; continue; } if(*p++ == '\0') { cp = --q; return(p); } } } search(ptr) struct label *ptr; { struct label *rp; rp = labtab; while(rp < ptr) { if(cmp(rp->asc, ptr->asc) == 0) return(rp); rp++; } return(0); } dechain() { struct label *lptr; struct reptr *rptr, *trptr; for(lptr = labtab; lptr < lab; lptr++) { if(lptr->address == 0) printf2("Undefined label: %s\n", lptr->asc); if(lptr->chain) { rptr = lptr->chain; while(trptr = rptr->re1) { rptr->re1 = lptr->address; rptr = trptr; } rptr->re1 = lptr->address; } } } search(ptr) struct label *ptr; { struct label *rp; rp = labtab; while(rp < ptr) { if(cmp(rp->asc, ptr->asc) == 0) return(rp); rp++; } return(0); } dechain() { struct label *lptr; struct reptr *rptr, *trptr; for(lptr = labtab; lptr < lab; lptr++) { if(lptr->address == 0) printf2("Undefined label: %s\n", lptr->asc); if(lptr->chain) { #include "sed.h" execute(file) { extern fout; register char *p1, *p2; register c; int i, fi; char cflag; if (file) { if ((f = open(file, 0)) < 0) { printf2("Can't open %s\n", file); } } else f = 0; ebp = ibuf; cbp = ibuf; if(pending) { rep = pending; cflag = 1; pending = 0; goto com; } for(;;) { if((spend = gline(linebuf)) == -1) { close(f); return(0); } for(rep = ptrspace; rep->command; ) { p1 = rep->ad1; p2 = rep->ad2; cflag = 0; if(p1) { if(rep->inar) { cflag++; if(*p2 == CEND) { p1 = 0; goto com; } if(*p2 == CLNUM) { c = p2[1]; if(lnum == tlno[c]) { rep->inar = 0; } if(lnum > tlno[c]) rep->inar = cflag = 0; goto com; } if(match(p2, 0) || dolflag){ rep->inar = 0; } } else if(*p1 == CEND) { if(dolflag) cflag++; goto com; }else if(*p1 == CLNUM) { c = p1[1]; if(lnum == tlno[c]) { cflag++; if(p2)  rep->inar = 1; goto com; } if(lnum > tlno[c]) { rep++; continue; } } else { if(match(p1, 0)) { cflag++; if(p2) rep->inar = 1; } } } else cflag++; com: if(cflag) command(); if(delflag) break; if(jflag) { jflag = 0; rep = rep->re1; } else rep++; } if(!nflag && !delflag) printf("%s\n", linebuf); if(aptr > abuf) { arout(); } delflag = 0; } } match(expbuf, gf) char *expbuf; { register char *p1, *p2, c; if(gf) { if(*expbuf) return(0); p1 = linebuf; p2 = genbuf; while(*p1++ = *p2++); locs = p1 = loc2; } else { p1 = linebuf; locs = 0; } p2 = expbuf; if(*p2++) { loc1 = p1; return(advance(p1, p2)); } /* fast check for first character */ if(*p2 == CCHR) { c = p2[1]; do { if(*p1 != c) continue; if(advance(p1, p2)) { loc1 = p1; return(1); } } while(*p1++); return(0); } do { if(advance(p1, p2)) { loc1 = p1; return(1); } } while(*p1++); return(0); } advance(alp, aep) { register char *lp, *ep, *curlp; char c; char *nextep, *bbeg; int ct; /* printf("*lp = %c, %o\n*ep = %c, %o\n", *lp, *lp, *ep, *ep); /*DEBUG*/ lp = alp; ep = aep; for (;;) switch (*ep++) { case CCHR: if (*ep++ == *lp++) continue; return(0); case CDOT: if (*lp++) continue; return(0); case CNL: case CDOL: if (*lp==0) continue; return(0); case CEOF: loc2 = lp; return(1); case CCL: c = *lp++ & 0177; if(ep[c>>3] & bittab[c & 07]) { ep =+ 16; continue; } return(0); case CBRA: braslist[*ep++] = lp; continue; case CKET: braelist[*ep++] = lp; continue; case CBACK: bbeg = braslist[*ep]; ct = braelist[*ep++] - bbeg; if(ecmp(bbeg, lp, ct)) { lp =+ ct; continue; } return(0); case CBACK|STAR: bbeg = braslist[*ep]; ct = braelist[*ep++] - bbeg; curlp = lp; while(ecmp(bbeg, lp, ct)) lp =+ ct; while(lp >= curlp) { if(advance(lp, ep)) return(1); lp =- ct; } return(0);  case CDOT|STAR: curlp = lp; while (*lp++); goto star; case CCHR|STAR: curlp = lp; while (*lp++ == *ep); ep++; goto star; case CCL|STAR: curlp = lp; do { c = *lp++ & 0177; } while(ep[c>>3] & bittab[c & 07]); ep =+ 16; goto star; star: if(--lp == curlp) { continue; } if(*ep == CCHR) { c = ep[1]; do { if(*lp != c) continue; if(advance(lp, ep)) return(1); } while(lp-- > curlp); return(0); } do { if(lp == locs) break; if (advance(lp, ep)) return(1); } while (lp-- > curlp); return(0); default: printf2("RE botch\n"); } } substitute() { if(match(rep->re1, 0) == 0) return(0); sflag = 1; dosub(rep->rhs); if(rep->gfl) { while(*loc2) { if(match(rep->re1, 1) == 0) break; dosub(rep->rhs); } } return(1); } cclass(aset, ac, af) { register char *set, c; register n; set = aset; if ((c = ac) == 0) return(0); n = *set++; while (--n) if (*set++ == c) return(af); return(!af); } dosub(rhsbuf) char *rhsbuf; { register char *lp, *sp, *rp; int c; lp = linebuf; sp = genbuf; rp = rhsbuf; while (lp < loc1) *sp++ = *lp++; while(c = *rp++) { if (c=='&') { sp = place(sp, loc1, loc2); continue; } else if (c<0 && (c =& 0177) >='1' && c < NBRA+'1') { sp = place(sp, braslist[c-'1'], braelist[c-'1']); continue; } *sp++ = c&0177; if (sp >= &genbuf[LBSIZE]) printf2("output line too long.\n"); } lp = loc2; loc2 = sp + linebuf - genbuf; while (*sp++ = *lp++) if (sp >= &genbuf[LBSIZE]) { printf2("Output line too long.\n"); } lp = linebuf; sp = genbuf; while (*lp++ = *sp++); spend = lp; } place(asp, al1, al2) { register char *sp, *l1, *l2; sp = asp; l1 = al1; l2 = al2; while (l1 < l2) { *sp++ = *l1++; if (sp >= &genbuf[LBSIZE]) printf2("Output line too long.\n"); } return(sp); } command() { register int i; register char *p1, *p2; if(rep->command & GCOM) if(match(rep->re2, 0) == 0) return; if(rep->command & VCOM) if(match(rep->re2, 0) == 1) return; switch(rep->command & ~(GCOM | VCOM)) { case ACOM: *aptr++ = rep; if(aptr >= &abuf[ABUFSIZE]) { printf2("Too many appends after line %ld\n", lnum); } *aptr = 0; break; case CCOM: delflag = 1; if(!rep->inar) printf("%s\n", rep->re1); break; case DCOM: delflag++; break; case CDCOM: p1 = p2 = linebuf; while(*p1 != '\n') { if(*p1++ == 0) { delflag++; return(0); } } p1++; while(*p2++ = *p1++); spend = p2; jflag++;  break; case EQCOM: printf("%ld\n", lnum); break; case ICOM: printf("%s\n", rep->re1); break; case JCOM: jflag = 1; break; case LCOM: break; case NCOM: if(!nflag) printf("%s\n", linebuf); if(aptr > abuf) arout(); if((spend = gline(linebuf)) == -1) { pending = rep; delflag = 1; } break; case CNCOM: if(aptr > abuf) arout(); spend[-1] = '\n'; if((spend = gline(spend)) == -1) { pending = rep; delflag = 1; } break; case PCOM: if(nflag) printf("%s\n", linebuf); break; case CPCOM: if(nflag) { cpcom: p1 = linebuf; while(*p1 != '\n' && *p1 != '\0') p1++; i = *p1; *p1 = '\0'; printf("%s\n", linebuf); *p1 = i; } break; case QCOM: if(!nflag) printf("%s\n", linebuf); if(aptr > abuf) arout(); flush(); exit(0); case RCOM: *aptr++ = rep; if(aptr >= &abuf[ABUFSIZE]) printf2("Too many reads after line%ld\n", lnum); *aptr = 0; break; case SCOM: i = substitute(); if(i && nflag && rep->pfl) if(rep->pfl == 1) printf("%s\n", linebuf); else goto cpcom; if(i && rep->fcode) goto wcom; break; case TCOM: if(sflag == 0) break; sflag = 0; jflag = 1; break; wcom: case WCOM: i = 0; while(linebuf[i++]); linebuf[--i] = '\n'; write(rep->fcode, linebuf, i + 1); linebuf[i] = '\0'; break; } } gline(address) char *address; { register char *p1, *p2; register c; p1 = address; p2 = cbp; for (;;) { if (p2 >= ebp) { if ((c = read(f, ibuf, 512)) <= 0) { return(-1); } p2 = ibuf; ebp = ibuf+c; } if ((c = *p2++) == '\n') { if(p2 >= ebp) { if((c = read(f, ibuf, 512)) <= 0) { close(f); if(eargc == 0) dolflag = 1; } dolflag = 1; p2 = ibuf; ebp = ibuf + c; } break; } if(c) if(p1 < lbend) *p1++ = c; } lnum++; *p1++ = 0; cbp = p2; return(p1); } ecmp(a, b, count) char *a, *b; { while(count--) if(*a++ != *b++) return(0); return(1); } arout() { int i, fi; aptr = abuf - 1; while(*++aptr) { if(((*aptr)->command & ~(GCOM|VCOM))==ACOM) printf("%s\n", (*aptr)->re1); else { if((fi = open((*aptr)->re1, 0)) < 0) continue; flush(); while((i = read(fi, genbuf, 512)) == 512) write(fout, genbuf, 512); if(i) write(fout, genbuf, i); close(fi); } } aptr = abuf; *aptr = 0; } *p1++ = 0; cbp = p2; return(p1); } ecmp(a, b, count) char *a, *b; { while(count--) if(*a++ !# /* 11/26/75 mod3.30.04 */ #define INTR 2 #define QUIT 3 #define LINSIZ 1024 #define ARGSIZ 50 #define STKSIZ 10 #define TRESIZ 128 #define SCCMODE 0100000 #define QUOTE 0200 #define GLOB "/etc/glob" #define GOTO "/bin/goto" #define PWD "/bin/pwd" #define SHELL "/bin/sh" /* * node types: * TCOM: program {syntax type 3.2} * TPAR: ( stuff ) {syntax type 3.1} * TFIL: pipe node {syntax type 2.2, 2.3} * TLST: list node {syntax type 1.2, 1.3} */ #define TCOM 1 #define TPAR 2 #define TFIL 3 #define TLST 4 /* * flags * FCAT: concatenate to output file. * FECAT: concatenate to errput file. * FPIN: input from pipe * FPOU: output to pipe. * FPAR: last spinoff from parenthesized expression, don't fork again. * FAND: no wait for termination of child. * FINT: clear traps, if set (INTR, QUIT); default input from /dev/null. * FPRS: print pid of child after forking. */ #define FCAT 1 #define FECAT 2 #define FPIN 4 #define FPOU 8 #define FPAR 16 #define FAND 32 #define FINT 64 #define FPRS 128 /* * node descriptions: * program: DTYP, DFLG, DIN, DOUT, DERR, DPRG, DCOM, DARG1, DARG2, ... * paren: DTYP, DFLG, DIN, DOUT, DERR, DSPR * pipe: DTYP, DFLG, DLEF, DRIT * list: DTYP, DFLG, DLEF, DRIT */ #define DTYP 0 #define DFLG 1 #define DLEF 2 #define DIN 2 #define DRIT 3 #define DOUT 3 #define DERR 4 #define DSPR 5 #define DPRG 5 #define DCOM 6 #define DARG1 7 #define DARG2 8 struct list { int type; char flagc; char cchar; struct list *left; struct list *right; }; struct paren { int type; int flag; char *input; char *output; char *errput; struct list *subpar; char *args[0]; }; struct progm { int type; int flag; char *input; char *output; char *errput; char *program; char *pname; char *arg1; char *arg2; }; #define ENOENT 2 #define E2BIG 7 #define ENOEXEC 8 #define ENOMEM 12 #define EACCES 13 #define ENOTDIR 20 #define EDIRECT 13 char *dolp; #define STKP stk[0] int stk[STKSIZ+1]; char pidp[6]; char nbuf[6]; int ldivr; char **dolv; int dolc; char *promp "% "; char *linep; char line[LINSIZ]; char *elinep line+LINSIZ-30; char **argp; char *args[ARGSIZ]; char **eargp args+ARGSIZ-1; int *treep; int treecnt; int trebuf[TRESIZ]; int *treeend trebuf+TRESIZ; char peekc; char error; char uid; char setintr; char *arginp; int acctf; int readf; char *intrf; int prof; int onelflg; int exitcod; int echoflg; char *seta[26]; char tty[] "/dev/lnXX"; char *qc; char qlist[] ": \t;&<>%()|^*?[\"'$\\"; char *home; char *endcore; char *endptr; int errno; int wasintr; char *gointr; char *goeof; /* char expath[32], *expathp; */ char *mesg[] { 0, "Hangup", 0, "Quit", "Illegal instruction", "Trace/BPT trap", "IOT trap", "EMT trap", "Floating exception", "Killed", "Bus error", "Memory fault", "Bad system call", "Broken pipe", "Alarm timeout", "Software kill", "Sig 16", "Sig 17", "Sig 18", "Sig 19", }; char *acct_name "/usr/adm/sh_acct"; struct stime { long uproct; long sproct; long cputim; long systim; } timeb; main(c, av) int c; char **av; { register *f; register char *cptr, **v; int pv[2]; int stopprof(); int ln; int pwdstat; struct{ char lobyte; char hibyte; }; endptr = endcore = sbrk(0); dup(1); /* if error output (2) not open, open it. */ for(cptr=3; cptr<15; close(cptr++)); if(pipe(f=pv)!= -1) { if(!fork()) { close(*f++); close(1); dup(*f); close(*f); write(1, "/", 1); execl(PWD, PWD+5, 0); exit(9); } close(f[1]); wait(&pwdstat); home = rdval(*f, 0, 0); close(*f); } ln = lnxx(0); if(ln.lobyte == 'x' && ln.hibyte == 'x'){ ln = lnxx(1); if(ln.lobyte == 'x' && ln.hibyte == 'x') ln = lnxx(2); } tty[7] = ln; tty[8] = ln>>8; btoa(getpid(), pidp+5); f = pidp; *f++ =| '00'; *f =| '00'; v = av; cptr = acct_name; promp = "% "; if(((uid = getuid())&0377) == 0) { promp = "# "; acct_name[10] = 'u'; } acctf = open(cptr, 1); f = *v++; if(c == 1 && *f == '-') if((prof = open("profile.sh", 0)) == -1) prof = 0; while(--c > 0 && promp) { cptr = *v++; if(*cptr++ == '-') { switch(*cptr) { default: prs("Bad arg: "); err(--cptr); case 'c': if(--c <= 0) exit(4); arginp = *v; case '\0': break; case 'e': case 'v': echoflg = 1; continue; case 'i': *f = '-'; continue; case 't': onelflg = 2; *--v =+ 2; } *f = '-'; } else { readf = dup(0); close(0); openi(*--v); intrf = *v; } promp = 0; } dolv = v; dolc = c; *--v = f; if(*f == '-') { setintr++; signal(QUIT, 1); signal(INTR, 1); if(prof)setintr = -1; } setexit(); for(;;) { if(wasintr == 1) wasintr = 0; if(wasintr > 0) { wasintr = -1; if(intrf) if((prof = open(intrf, 0)) == -1) prof = 0; if(xgoto(gointr)) { if(prof) close(prof); prof = 0; signal(INTR, 0); wasintr = 0; } } if(promp && !prof) prs(promp); echoflg =<<2; qc = qlist; if((peekc = getc()) == ':') while(getc() != '\n'); else { qc++; main1(); if(setintr<0) { signal(INTR, stopprof); setintr = 1; } } } } main1() { register char c, *cp; register *t; argp = args; linep = line; error = 0; do { cp = linep; if(argp == eargp) { while(getc() != '\n'); err("Too many tokens"); reset(); } word(); } while(*cp != '\n'); treep = trebuf; treecnt = 0; if(error == 0) t = syntax(args, argp); if(error != 0) err("syntax error"); else execute(t); } word() { register char c, c1; register (*qf)(); extern getc(), reade(); *argp++ = linep; loop: switch(c = getc()) { case ' ': case '\t': goto loop; case '\'': case '"': c1 = c; qc = qlist+16; qf = (c1 == '"')? reade: getc; while((c=(*qf)()) != c1) { if(c == '\n') { error++; peekc = c; return; } *linep++ = c|QUOTE; } qc = qlist+1; goto pack; case '&': case ';': case '%': case '<': case '>': case '(': case ')': case '|': case '^': case '\n': *linep++ = c; *linep++ = '\0'; return; default: peekc = c; } pack: for(;;) { c = getc(); if(any(c, " '\"\t;&%<>()|^\n")) { peekc = c; if(any(c, "\"'")) goto loop; *linep++ = '\0'; return; } *linep++ = c; } } tree(n) int n; { register *t; t = treep; treep =+ n; treecnt++; if (treep>treeend) { prs("Command table overflow\n"); error++; reset(); } return(t); } reade() { return(echo(readc())); } echo(c) { switch(echoflg) { case 0: return(c); case 1<<10: /* (1<<2)<<8 only. */ case 1<<2: write(2, "* ", 2); case 1<<8: if(echoflg != 1<<2) write(2, "\\\n", 1); c =& 0177; case 1: write(2, &c, 1); break; case 1<<4: write(2, "\\\n", 2); } echoflg = 1; return(c); } getc() { register char c, n, *temp; if(peekc) { c = peekc; peekc = 0; return(c); } for(;;) { c = readc(); if(c == '$') { c = readc(); temp = "\\$X"; temp[2] = c; if((n = c-'0')>=0 && c<='9') { if(n > dolc) continue; else temp = dolv[n]; } else if((n = c-'a')>=0 && c<='z') { if((temp = seta[n]) == 0) continue; } else if(c == '$') temp = pidp; else if(c == '.') temp = home; else if(c == 'T' || c == '_') temp = tty; else if(c == 'E') { temp = nbuf; temp[3] = 0; temp[2] = (exitcod & 7) + '0'; temp[1] = (exitcod>>3 & 7) + '0'; temp[0] = (exitcod>>6 & 3) + '0'; } else if(c == 'N') temp = btoa(dolc, nbuf+5); else if(c == 'R') temp = btoa(exitcod, nbuf+5); else if(c == 'P') temp = btoa(prof, nbuf+5); else if(c == 'F') temp = btoa(readf, nbuf+5); else if(c == 'V') { if(echoflg) temp = "-v"; else continue; } else if(c == 'I') temp = btoa(setintr, nbuf+5); else if(c=='Z') temp = btoa(endptr); if(STKP >= STKSIZ) err("'$' nesting error"); else { stk[STKP] = dolp; STKP++; dolp = temp; } continue; } if(c=='\\') { c=readc(); if(c=='\n') { echoflg =<<4; c = ' '; } else if(any(c, qc)) { c =| QUOTE; echoflg =<<8; } else { peekc = c; c = '\\'; } } break; } echo(c); if(linep == elinep) { linep--; while(getc() != '\n'); linep++; err("Too many characters"); reset(); } return(c); } readc() { char cc; register c; while(dolp) { c = *dolp++; if(c != '\0') return(c =& 0177); else dolp = stk[--STKP]; } if (arginp) { if (arginp == 1) exit(exitcod); if ((c = *arginp++) == 0) { arginp = 1; c = '\n'; } return(c); } if (onelflg==1) exit(exitcod); if(read1(prof, &cc)) { if(!prof || !setintr) exit(exitcod); close(prof); prof = 0; if(wasintr<0) { wasintr = 0; signal(INTR, 0); } cc = '\n'; } if (cc=='\n' && onelflg) onelflg--; return(cc); } /* * syntax * empty * syn1 */ syntax(p1, p2) char **p1, **p2; { while(p1 < p2) { if(any(**p1, ";&\n")) p1++; else return(syn1(p1, p2)); } return(0); } /* * syn1 * syn2 * syn2 &&C syntax * syn2 & syntax * syn2 ; syntax */ syn1(p1, p2) char **p1, **p2; { register char **p; register *t, *t1; int l; l = 0; for(p=p1; p= 'a' && **p <= 'z' && p[0][1] == 0) t1->cchar = **p++; } t[DRIT] = syntax(p, p2); return(t); } } if(l == 0) return(syn2(p1, p2)); error++; } /* * syn2 * syn3 * syn3 | syn2 * syn3 ^ syn2 */ syn2(p1, p2) char **p1, **p2; { register char **p; register int l, *t; l = 0; for(p=p1; p!=p2; ) switch(**p++) { case '(': l++; continue; case ')': l--; continue; case '|': case '^': if(p1 == p) { error++; return(0); } if(l == 0) { t = tree(4); t[DTYP] = TFIL; t[DLEF] = syn3(p1, p-1); t[DRIT] = syn2(p, p2); t[DFLG] = 0; return(t); } } return(syn3(p1, p2)); } /* * syn3 * ( syn1 ) [ < in ] [ > [ > ] out ] [ % [ % ] err ] * word word* [ < in ] [ > [ > ] out ] [ % [ % ] err ] */ syn3(p1, p2) char **p1, **p2; { register char **p; char **lp, **rp; register *t, *ioep; int n, l, ioe[3], flg; char c; flg = 0; if(**p2 == ')') flg =| FPAR; lp = 0; rp = 0; ioep = ioe+3; *--ioep = 0; *--ioep = 0; *--ioep = 0; n = 0; l = 0; for(p=p1; p!=p2; ) switch(c = **p++) { case '(': if(l == 0) { if(lp != 0) error++; lp = p; } l++; continue; case ')': l--; if(l == 0) rp = p-1; continue; case '%': ioep++; case '>': ioep++; if(l) { ioep = ioe; continue; } if(p != p2) { if(**p++ == c) flg =| (c == '%') ? FECAT : FCAT; else if(**--p == '%') **p = 0377; } case '<': if(l) continue; if(p == p2 || any(**p, "<>%(") || *ioep) { error++; continue; } *ioep = *p++; ioep = ioe; continue; default: if(l == 0) p1[n++] = p[-1]; } if(lp != 0) { if(n != 0) error++; t = tree(6); t[DTYP] = TPAR; t[DSPR] = syn1(lp, rp); goto out; } if(n == 0) error++; p1[n++] = 0; t = tree(n+6); t[DTYP] = TCOM; for(l=0; l9 || *cp1++ >dolc || *cp1) { prs("shift: argument?\n"); exitcod = 4; return; } t1 = dolv + *--cp1;  for(cp2 = dolc - *cp1 +1; --cp2; *t1++ = t1[1]); dolc--; return; } if(equal(cp1, "login")) { if(promp != 0 && prof == 0) { close(acctf); if(readf) close(readf); execv("/bin/login", t1+DCOM); } noex(); return; } /* newgrp not implemented. if(equal(cp1, "newgrp")) { if(promp != 0 && prof == 0) { close(acctf); if(readf) close(readf); execv("/bin/newgrp", t1+DCOM); } noex(); return; } */ /* home -- use chdir $. if(equal(cp1, "home")) { if(!home || !*home || chdir(home)<0) noex(); return; } */ if(equal(cp1, "wait")) { if(t1[DARG1]) cp2 = atob(t1[DARG1]); else cp2 = -1; wt = signal(INTR, catchintr); pwait(cp2, 0); signal(INTR, wt); wasintr = 0; return; } if(equal(cp1, ":")) return; if((cp2=equal(cp1, "return")) || equal(cp1, "exit")) { if(t1[DARG1]) exitcod = atob(t1[DARG1]); if(cp2 && prof) { close(prof); prof = 0; } else if(promp==0 || prof) { seek(0,0,2); exit(exitcod);  } return; } if(equal(cp1, "onintr")) { if(setintr) { setintr = 1; if(t1[DARG1]) noex(); else signal(INTR, 1); return; } if(t1[DARG1]==0) { signal(INTR, 0); return; } gointr = rdval(0, 0, t1[DARG1]); wasintr = 0; signal(INTR, catchintr); return; } if(equal(cp1, "onend")) { if(t1[DARG1]) goeof = rdval(0, 0, t1[DARG1]); else goeof = 0; return; } if(equal(cp1, "=")) { if((cp1 = t1[DARG1]) == 0 || (*cp1 =- 'a')<0 || *cp1++ > 25 || *cp1 || (seta[*--cp1] = rdval((t1[DFLG]&FPIN?pf1:0), t1[DLEF], t1[DARG2])) == 0) err("'=' error"); return; } if(equal(cp1, "open")) { if(readf) close(readf); if(!t1[DARG1]) if(t1[DFLG]&FPIN) { readf = dup(pf1); return; } else t1[DARG1] = tty; readf = open(t1[DARG1],0); return; } if(equal(cp1, "read")) { cp2 = linep; if(t1[DFLG]&FPOU) cp1 = pf2[1]; else if(t1->output) { if((cp1=openo(t1->output,t1[DFLG]&FCAT))&0100000)  return; } else cp1 = 1; if(read1(readf, cp2)) { if(xgoto(goeof)) err("read - EOF"); *cp2 = 0; } while(*cp2 && *cp2 != '\n') { write(cp1, cp2, 1); if(read1(readf, cp2)) break; } write(cp1, "\n", 1); if(!(t1[DFLG]&FPOU) && t1[DRIT]) close(cp1); return; } case TPAR: f = t1[DFLG]; i = 0; if((f&FPAR) == 0) for(wt=10; ; wt =+ 10) { if ((i=fork()) != -1) break; if(promp == 0 && wt<60) sleep(wt); else { err("Cannot fork; try again"); return; } } if(i != 0) { if((f&FPRS) != 0) { if(t1->cchar) { seta[t1->cchar - 'a'] = rdval(0, 0, btoa(i, nbuf+5)); } else { prn(i); prs("\n"); } } if((f&FAND) != 0) return; if((f&FPOU) == 0) pwait(i, t); return; } promp = 0; /* show err this is a child */ if(prof) { close(0); dup(prof); close(prof); } if(t1[DERR]) { i = openo(t1->errput, f&FECAT); close(2); dup(i); close(i); } if(t1[DLEF]) { close(0); openi(t1->input); } if(t1[DRIT]) { close(1); if(t1->output[0] == -1) dup(2); else openo(t1->output, f&FCAT); } if((f&FPIN) != 0) { close(0); dup(pf1); close(pf1); } if((f&FPOU) != 0) { close(1); dup(pf2[1]); close(pf2[0]); close(pf2[1]); } if((f&FINT)!=0 && t1[DLEF]==0 && (f&FPIN)==0) { close(0); open("/dev/null", 0); } if((f&FINT) == 0 && setintr) { signal(INTR, 0); signal(QUIT, 0); } if(t1[DTYP] == TPAR) { if(t1 = t1[DSPR]) t1[DFLG] =| f&FINT; execute(t1); exit(exitcod); } close(acctf); if(readf) close(readf); if(scan(t1, 0)){ t1[DSPR] = GLOB; execv(t1[DSPR], t1+DSPR); t1->pname = GLOB; noex(); } scan(t1, 1); cp1 = *(t1 = t+DCOM); cp2 = shexec(cp1, t1); copy(*t1, copy("/usr/bin/", linep)); cp2 =+ shexec(linep+4, t1); cp2 =+ shexec(linep, t1); prs(*t1); err(cp2? ": permission denied!": ": not found"); case TFIL: f = t[DFLG]; if(pipe(pv)<0) err("Cannot create pipe"); t1 = t[DLEF]; t1[DFLG] =| FPOU | (f&(FPIN|FINT|FPRS)); execute(t1, pf1, pv); close(pv[1]); t1 = t[DRIT]; t1[DFLG] =| FPIN | (f&(FPOU|FINT|FAND|FPRS)); execute(t1, *pv, pf2); close(pv[0]); return; case TLST: f = t[DFLG]&FINT; if(t1 = t[DLEF]) t1[DFLG] =| f; execute(t1); if(t1 = t[DRIT]) t1[DFLG] =| f; execute(t1); return; } } noex() { register t1; prs(t1->pname); err(": cannot execute"); } openi(ifile) { register i; if((i = open(ifile, 0)) < 0) { prs(ifile); err(": cannot open"); i=0; } return(i); } openo(of, flg) { register i; if(flg && (i = open(of, 1)) > 0) seek(i, 0, 2); else if((i=creat(of, 0666)) < 0) { prs(of); err(": cannot create"); } return(i); } err(s) char *s; { prs(s); prs("\n"); if(promp == 0) { seek(0, 0, 2); exit(8); } exitcod = 8; return; } any(c, as) int c; char *as; { register char *s; s = as; while(*s) if(*s++ == c) return(1); return(0); } equal(as1, as2) char *as1, *as2; { register char *s1, *s2; s1 = as1; s2 = as2; while(*s1++ == *s2) if(*s2++ == '\0') return(1); return(0); } pwait(i, t) int i, *t; { register p, e; int s; int catchintr(); if(i != 0) for(;;) { times(&timeb); time(&timeb.uproct); p = wait(&s); if(wasintr > 0) { /* wait terminated by interrupt */ if(t == 0) /* wait called by wait command, */ break; /* stop waiting. */ p = wait(&s); } if(p == -1) break; e = s&0177; if(e == 2 && wasintr > 0) /* process killed by intr */ e = 0; if(mesg[e] != 0) { if(p != i) { prn(p); prs(": "); } prs(mesg[e]); if(s&0200) prs(" -- Core dumped"); } exitcod = s>>8; if(e != 0) err(""); if(i == p) { acct(t); break; } else acct(0); } } acct(t) int *t; { if(t == 0) enacct("**gok"); else if(*t == TPAR) enacct("()"); else enacct(t[DCOM]); } enacct(as) char *as; { struct stime timbuf; struct { char cname[14]; char shf; char uid; long datet; long realt; long bcput; long bsyst; } tbuf; register i; register char *np, *s; if(acctf == -1) return; s = as; times(&timbuf); time(&timbuf.uproct); tbuf.realt = timbuf.uproct - timeb.uproct; tbuf.bcput = timbuf.cputim - timeb.cputim; tbuf.bsyst = timbuf.systim - timeb.cputim; for(np = s; i = *s++; ) if(i=='/') np=s; for (i=0; i<14; i++) { if(tbuf.cname[i] = *np) np++; } tbuf.datet = timbuf.uproct; tbuf.uid = uid; tbuf.shf = 0; if (promp==0) tbuf.shf = 1; seek(acctf, 0, 2); write(acctf, &tbuf, sizeof(tbuf)); } read1(file, where) { register i; while((i = read(file, where, 1)) != 1 && wasintr == 2) wasintr++; return(--i != 0); } catchintr() { wasintr=2; signal(INTR, 1); } stopprof() { signal(INTR, 1); seek(prof, 0, 2); wasintr=1; } char *copy(source,sink) char source[], sink[]; { /* copy strings */ register char *p1, *p2; p1 = source; p2 = sink; while(*p2++ = *p1++); return(--p2); } rdval(pipef, lef, arg2p) char *arg2p; int *pipef; { register char c, *st, *endp; endp = st = endptr; if(!arg2p && !pipef && lef) { if((pipef = open(lef, 0)) < 0) return(0); } else lef = 0; do { if(endp >= endcore) if(sbrk(64)<0) return(0); else endcore =+ 64; if(arg2p == 0) { if(read1(pipef, endp) || *endp == '\n') *endp = '\0'; } else *endp = *arg2p++; } while(*endp++); endptr = endp; if(lef) close(pipef); return(st); } xgoto(where) char *where; { register i; int j; if(!where || !*where) return(1); if(!(i = fork())) { if(prof) { close(0); dup(prof); close(prof);  } execl(GOTO, GOTO+5, where, 0); exit(9); } if(i == -1) return(i); pwait(i, 0); return(exitcod); } atob(ptr) char *ptr; { register char *p; register n, base; static char base0; n = 0; p = ptr; base = 10; if(*p == '-') p++; if(*p == '0') { base = 8; p++; } base0 = base + '0'; while(*p >= '0' && base0 > *p) { n =* base; n =+ *p++; n =- '0'; } if(*ptr == '-') n = -n; return(n); } #define ENOENT 2 #define E2BIG 7 #define ENOEXEC 8 #define ENOMEM 12 #define EACCESS 13 #define ENOTDIR 20 #define EDIRECT 13 #define SHELL "/bin/sh" int ldivr; char nbuf[6]; shexec(afile, aargp) char *afile, *aargp[]; { register char *file, **rargp; extern errno; file = afile; rargp = aargp; execv(file, rargp); /* temp */ if(!errno || errno & 0177700) errno = EDIRECT; if(errno == ENOEXEC) { *rargp = file; *--rargp = SHELL+5; execv(SHELL, rargp); if(errno == ENOENT || errno == ENOTDIR) err("No Shell!"); } switch (errno) { case E2BIG: prs(*rargp); err(": arg list too long"); case ENOMEM: prs(*rargp); err(": not enough core"); default: prs(*rargp); prs(": unknown error (errno="); prn(errno); err(")."); case EACCESS: return(1); case ENOENT: case ENOTDIR: return(0); } } prs(as) char *as; { register char *s; s = as; while(*s) write(2, s++, 1); } prn(n) { prs(btoa(n, nbuf+5)); } btoa(n, ptr) char *ptr; { register char *p; register v; p = ptr; *p = 0; v = n; do { v = ldiv(0, v, 10); *--p = ldivr | '0'; } while(v); return(p); } ng"); case ENOMEM: prs(*rargp); err(": not enough core"); default: prs(*rargp); prs(": unknown error (errno="); prn(errno); err(")."); case EACCESS: return(1); case ENOENT: case ENOTDIR: return(0); } } prs(as) char *as; { register char *s; s = as; while(*s) write(2, s++, 1); } prn(n) { prs(btoa(n, nbuf+5)); } btoa(n, ptr) char *ptr; { register char *p; register v; p = ptr; *p = 0; v = n; do { v = ldiv(0, v, 10); *--p = ldivr | '0'; } while(v); return(p)/* size -- determine object size */ main(argc, argv) char **argv; { int buf[010], f, ac; long sum, itol(); ac = argc; if (ac==1) { *argv = "a.out"; ac++; --argv; } while(--ac) { ++argv; if((f=open(*argv, 0))<0) { printf("%s not found\n", *argv); continue; } read(f, buf, 0020); if(buf[0]!=0410 && buf[0]!=0407 && buf[0]!=0411 && buf[0]!=0405) { printf("%s not an object file\n", *argv); close(f); continue; } if (argc>2) printf("%s: ", *argv); printf("%l+%l+%l=", buf[1],buf[2],buf[3]); sum = itol(0, buf[1])+itol(0, buf[2])+itol(0, buf[3]); printf("%D (0%O)\n", sum, sum); close(f); } exit(0); } v = "a.out"; ac++; --argv; } while(--ac) { ++argv; if((f=open(*argv, 0))<0) { printf("%s not found\n", *argv); continue; } read(f, buf, 0020); if(buf[0]!=0410 && buf[0]!=0407 && buf[0]!=0411 && buf[0]!=0405) { printf("%s not an object file\n", *argv); close(f); continue; } if (argc>2) printf("%s: ", *argv); printf("%l+%l+%lmain(argc, argv) char **argv; { int c, n; char *s; n = 0; if(argc < 2) { printf("arg count\n"); exit(); } s = argv[1]; while(c = *s++) { if(c<'0' || c>'9') { printf("bad character\n"); exit(); } n = n*10 + c - '0'; } sleep(n); } d\n", *argv); continue; } read(f, buf, 0020); if(buf[0]!=0410 && buf[0]!=0407 && buf[0]!=0411 && buf[0]!=0405) { printf("%s not an object file\n", *argv); close(f); continue; } if (argc>2) printf("%s: ", *argv); printf("%l+%l+%l#define L 512 #define N 7 #define C 20 #define MEM (16*2048) #define NF 10 int ibuf[259]; int obuf[259]; char *file; char *filep; int nfiles; int nlines; int ntext; int *lspace; char *tspace; int cmp(); int cmpa(); int (*compare)() cmpa; int term(); int mflg; int uflg; char *outfil; char tabchar; int eargc; char **eargv; char zero[256]; char fold[256] { 0200,0201,0202,0203,0204,0205,0206,0207, 0210,0211,0212,0213,0214,0215,0216,0217, 0220,0221,0222,0223,0224,0225,0226,0227, 0230,0231,0232,0233,0234,0235,0236,0237, 0240,0241,0242,0243,0244,0245,0246,0247, 0250,0251,0252,0253,0254,0255,0256,0257, 0260,0261,0262,0263,0264,0265,0266,0267, 0270,0271,0272,0273,0274,0275,0276,0277, 0300,0301,0302,0303,0304,0305,0306,0307, 0310,0311,0312,0313,0314,0315,0316,0317, 0320,0321,0322,0323,0324,0325,0326,0327, 0330,0331,0332,0333,0334,0335,0336,0337, 0340,0341,0342,0343,0344,0345,0346,0347, 0350,0351,0352,0353,0354,0355,0356,0357, 0360,0361,0362,0363,0364,0365,0366,0367, 0370,0371,0372,0373,0374,0375,0376,0377, 0000,0001,0002,0003,0004,0005,0006,0007, 0010,0011,0012,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0024,0025,0026,0027, 0030,0031,0032,0033,0034,0035,0036,0037, 0040,0041,0042,0043,0044,0045,0046,0047, 0050,0051,0052,0053,0054,0055,0056,0057, 0060,0061,0062,0063,0064,0065,0066,0067, 0070,0071,0072,0073,0074,0075,0076,0077, 0100,0101,0102,0103,0104,0105,0106,0107, 0110,0111,0112,0113,0114,0115,0116,0117, 0120,0121,0122,0123,0124,0125,0126,0127, 0130,0131,0132,0133,0134,0134,0136,0137, 0140,0101,0102,0103,0104,0105,0106,0107, 0110,0111,0112,0113,0114,0115,0116,0117, 0120,0121,0122,0123,0124,0125,0126,0127, 0130,0131,0132,0173,0174,0175,0176,0177 }; char nofold[256] { 0200,0201,0202,0203,0204,0205,0206,0207, 0210,0211,0212,0213,0214,0215,0216,0217, 0220,0221,0222,0223,0224,0225,0226,0227, 0230,0231,0232,0233,0234,0235,0236,0237, 0240,0241,0242,0243,0244,0245,0246,0247, 0250,0251,0252,0253,0254,0255,0256,0257, 0260,0261,0262,0263,0264,0265,0266,0267, 0270,0271,0272,0273,0274,0275,0276,0277, 0300,0301,0302,0303,0304,0305,0306,0307, 0310,0311,0312,0313,0314,0315,0316,0317, 0320,0321,0322,0323,0324,0325,0326,0327, 0330,0331,0332,0333,0334,0335,0336,0337, 0340,0341,0342,0343,0344,0345,0346,0347, 0350,0351,0352,0353,0354,0355,0356,0357, 0360,0361,0362,0363,0364,0365,0366,0367, 0370,0371,0372,0373,0374,0375,0376,0377, 0000,0001,0002,0003,0004,0005,0006,0007, 0010,0011,0012,0013,0014,0015,0016,0017, 0020,0021,0022,0023,0024,0025,0026,0027, 0030,0031,0032,0033,0034,0035,0036,0037, 0040,0041,0042,0043,0044,0045,0046,0047, 0050,0051,0052,0053,0054,0055,0056,0057, 0060,0061,0062,0063,0064,0065,0066,0067, 0070,0071,0072,0073,0074,0075,0076,0077, 0100,0101,0102,0103,0104,0105,0106,0107, 0110,0111,0112,0113,0114,0115,0116,0117, 0120,0121,0122,0123,0124,0125,0126,0127, 0130,0131,0132,0133,0134,0135,0136,0137, 0140,0141,0142,0143,0144,0145,0146,0147, 0150,0151,0152,0153,0154,0155,0156,0157, 0160,0161,0162,0163,0164,0165,0166,0167, 0170,0171,0172,0173,0174,0175,0176,0177 };  char nonprint[256] { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }; char dict[256] { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1, 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 }; struct field { char *code; char *ignore; int nflg; int rflg; int bflg; char *m[2]; char *n[2]; } fields[NF]; int proto[9] { nofold+128, zero+128, 0, 1, 0, 0,-1, 0,0 }; int nfields; int error 1; main(argc, argv) char **argv; { register a, i; char *arg; register int *p; int *q; copyproto(); eargv = argv; while (--argc > 0) { if(**++argv == '-') for(arg = *argv;;) { switch(*++arg) { case '\0': if(arg[-1] == '-') eargv[eargc++] = "-"; break; case 'o': if(--argc > 0) outfil = *++argv; continue; default: field(++*argv,1); break; } break; } else if (**argv == '+') { if(++nfields>=NF) { mess("Too many keys\n"); exit(1); } copyproto(); field(++*argv,0); } else eargv[eargc++] = *argv; } q = &fields[0]; for(a=1; a<=nfields; a++) { p = &fields[a]; for(i=0; i<5; i++) /*sensitive to sizeof(proto)*/ if(p[i] != proto[i]) goto next; for(i=0; i<5; i++) p[i] = q[i]; next: ; } if(eargc == 0) eargv[eargc++] = "-"; a = MEM; i = lspace = sbrk(0); while(brk(a) == -1) a =- 512; brk(a =- 512); /* for recursion */ a =- i; nlines = ((a-L)>>1) & 077777; nlines =/ 5; ntext = nlines*8; tspace = lspace+nlines; file = "/usr/tmp/stmXaa"; loop: filep = file; while(*filep != 'X') filep++; for(*filep = 'a';;(*filep)++) { if(stat(file, lspace) < 0) { a = creat(file, 0600); if(a >= 0) break; } if(*filep == 'z') { if(file[1] != 't') { file = "/tmp/stmXaa"; goto loop; } mess("Cannot locate temp\n"); exit(1); } } close(a); filep++; if ((signal(2, 1) & 01) == 0) signal(2, term); nfiles = eargc; if(!mflg) { ibuf[0] = -1; sort(); close(0); } for(a = mflg?0:eargc; a+N < nfiles; a=+N) { newfile(); merge(a, a+N); } if(a != nfiles) { oldfile(); merge(a, nfiles); } error = 0; term(); } sort() { register char *cp; register *lp, c; int done;  int i; int f; char * setfil(); done = 0; i = 0; do { cp = tspace; lp = lspace; while(lp < lspace+nlines && cp < tspace+ntext) { *lp++ = cp; while((*cp++ = c = getc(ibuf)) != '\n') { if(c >= 0) continue; cp--; close(ibuf[0]); if(i < eargc) { if((f = setfil(i++)) == 0) ibuf[0] = 0; else if(fopen(f, ibuf) < 0) cant(f); } else break; } if(c < 0) { done++; lp--; break; } } qsort(lspace, lp-lspace, 2, compare); if(done == 0 || nfiles != eargc) newfile(); else oldfile(); while(lp > lspace) { cp = *--lp; if(*cp) do putc(*cp, obuf); while(*cp++ != '\n'); } fflush(obuf); close(obuf[0]); } while(done == 0); } struct merg { char l[L]; int b[259]; }; merge(a,b) { struct merg *p; register char *cp, *dp; register i; struct {int *ip;}; int f; int j; int k, l, c; int muflg; p = lspace; j = 0; for(i=a; i < b; i++) { f = setfil(i); if(f == 0) p->b[0] = dup(0); else if(fopen(f, p->b) < 0) cant(f); ibuf[j] = p; if(!rline(p)) j++; p++; } do { i = j; qsort(ibuf, i, 2, compare); l = 0; while(i--) { cp = ibuf[i]; if(*cp == '\0') { l = 1; if(rline(ibuf[i])) { k = i; while(++k < j) ibuf[k-1] = ibuf[k]; j--; } } } } while(l); muflg = mflg & uflg; i = j; while(i > 0) { cp = ibuf[i-1]; if(uflg == 0 || muflg || (*compare)(&ibuf[i-1],&ibuf[i-2])) do putc(*cp, obuf); while(*cp++ != '\n'); if(muflg){ cp = ibuf[i-1]; dp = p; do { } while((*dp++ = *cp++) != '\n'); } do { if(rline(ibuf[i-1])) { i--; if(i == 0) break; if(i == 1) muflg = uflg; } cp = &ibuf[i]; while(--cp.ip>ibuf&&(*compare)(cp.ip,cp.ip-1)<0){ dp = *cp.ip; *cp.ip = *(cp.ip-1); *(cp.ip-1) = dp; } } while(muflg && (*compare)(&ibuf[i-1],&p) == 0); } p = lspace; for(i=a; ib[0]); p++; if(i >= eargc) close(creat(setfil(i))); } fflush(obuf); close(obuf[0]); } rline(mp) struct merg *mp; { register char *cp; register *bp, c; bp = mp->b; cp = mp->l; do { c = getc(bp); if(c < 0) return(1); *cp++ = c; } while(c != '\n'); return(0); } newfile() { if(fcreat(setfil(nfiles), obuf) < 0) { mess("Can't create temp\n"); term(); } nfiles++; } char * setfil(i) { if(i < eargc) if(eargv[i][0] == '-' && eargv[i][1] == '\0') return(0); else return(eargv[i]); i =- eargc; filep[0] = i/26 + 'a'; filep[1] = i%26 + 'a'; return(file); } oldfile() { if(outfil) { if(fcreat(outfil, obuf) < 0) { mess("Can't create output\n"); term(); } } else obuf[0] = 1; } cant(f) { mess("Can't open "); mess(f); mess("\n"); term(); } term() { register i; if(nfiles == eargc) nfiles++; for(i=eargc; i0; k<=nfields; k++) { fp = &fields[k]; pa = *i; pb = *j; if(k) { la = skip(pa, fp, 1); pa = skip(pa, fp, 0); lb = skip(pb, fp, 1); pb = skip(pb, fp, 0); } else { la = -1; lb = -1; } if(fp->nflg) { while(blank(*pa)) pa++; while(blank(*pb)) pb++; sa = sb = fp->rflg; if(*pa == '-') { pa++; sa = -sa; } if(*pb == '-') { pb++; sb = -sb; } if(sa != sb) sa = 0; for(ipa = pa; ipa pa && ipb > pb) if(b = *--ipb - *--ipa) a = b; while(ipa > pa) if(*--ipa != '0') return(sa ? -sa : sb); while(ipb > pb) if(*--ipb != '0') return(sa ? sa : sb); if(a) return(a*sa); if(*(pa=jpa) == '.') pa++; if(*(pb=jpb) == '.') pb++; while(pacode; ignore = fp->ignore; loop: while(ignore[*pa]) pa++; while(ignore[*pb]) pb++; if(pa>=la || *pa=='\n') if(pbrflg); else continue; if(pb>=lb || *pb=='\n') return(-fp->rflg); if((sa = code[*pb++]-code[*pa++]) == 0) goto loop; return(sa*fp->rflg); } if(uflg) return(0); return(cmpa(i, j)); } cmpa(i, j) int *i, *j; { register char *pa, *pb; pa = *i; pb = *j; while(*pa == *pb) { if(*pa++ == '\n') return(0); pb++; } return( *pa == '\n' ? fields[0].rflg: *pb == '\n' ?-fields[0].rflg: *pb > *pa ? fields[0].rflg: -fields[0].rflg ); } skip(pp, fp, j) struct field *fp; char *pp; { register i; register char *p; p = pp; if( (i=fp->m[j]) < 0) return(-1); while(i-- > 0) { if(tabchar != 0) { while(*p != tabchar) if(*p != '\n') p++; else goto ret; p++; } else { while(blank(*p)) p++; while(!blank(*p)) if(*p != '\n') p++; else goto ret; } } if(fp->bflg) while(blank(*p)) p++; i = fp->n[j]; while(i-- > 0) { if(*p != '\n') p++; else goto ret; } ret: return(p); } digit(c) { return(c <= '9' && c >= '0'); } mess(s) char *s; { while(*s) write(2, s++, 1); } copyproto() { register int i, *p, *q; p = proto; q = &fields[nfields]; for(i=0; ibflg++; break; case 'd': p->ignore = dict+128; break; case 'f': p->code = fold+128; break; case 'i': p->ignore = nonprint+128; break; case 'm': mflg++; continue; case 'n': p->nflg++; break; case 't': tabchar = *++s; if(tabchar == 0) s--; continue; case 'r': p->rflg = -1; continue; case 'u': uflg++; break; case '.': if(p->m[k] == -1) /* -m.n with m missing */ p->m[k] = 0; d = &fields[0].n[0]-&fields[0].m[0]; default: p->m[k+d] = number(&s); } compare = cmp; } } number(ppa) char **ppa; { int n; register char *pa; pa = *ppa; n = 0; while(digit(*pa)) { n = n*10 + *pa - '0'; *ppa = pa++; } return(n); } blank(c) { if(c==' ' || c=='\t') return(1); return(0); } int (*qscmp)(); int qses; qsort(a, n, es, fc) char *a; int n, es; int (*fc)(); { qscmp = fc; qses = es; qs1(a, a+n*es); } qs1(a, l) char *a, *l; { register char *i, *j, *es; char **k; char *lp, *hp; int n, c; es = qses; start: if((n=l-a) <= es) return; n = ((n/(2*es))*es) & 077777; hp = lp = a+n; i = a; j = l-es; for(;;) { if(i < lp) { if((c = (*qscmp)(i, lp)) == 0) { qsexc(i, lp =- es); continue; } if(c < 0) { i =+ es; continue; } } loop: if(j > hp) { if((c = (*qscmp)(hp, j)) == 0) { qsexc(hp =+ es, j); goto loop; } if(c > 0) { if(i == lp) { qstexc(i, hp =+ es, j); i = lp =+ es; goto loop; } qsexc(i, j); j =- es; i =+ es; continue; } j =- es; goto loop; } if(i == lp) { if(uflg) for(k=lp+2; k<=hp;) *(*k++)='\0'; if(lp-a >= l-hp) { qs1(hp+es, l); l = lp; } else { qs1(a, lp); a = hp+es; } goto start; } qstexc(j, lp =- es, i); j = hp =- es; } } qsexc(i, j) char *i, *j; { register char *ri, *rj, c; int n; n = qses; ri = i; rj = j; do { c = *ri; *ri++ = *rj; *rj++ = c; } while(--n); } qstexc(i, j, k) char *i, *j, *k; { register char *ri, *rj, *rk; char c; int n; n = qses; ri = i; rj = j; rk = k; do { c = *ri; *ri++ = *rk; *rk++ = *rj; *rj++ = c; } while(--n); } = l-hp) { qs1(hp+es, l); l = lp; } else { qs1(a, lp); a = hp+es; } goto start; } qstexc(j, lp =- es, i); j = hp =- es; } } qsexc(i, j) char *i, *j; { register char *ri, *rj, c; int n; n = qses; ri = i; rj = j; do { cint count 1000; int fnumber; int ibuf[259]; int obuf[259]; char fname[100]; char *ifil; char *ofil; main(argc, argv) char *argv[]; { register i, c, f; for(i=1; i='0' && *s<='9') n = n*10 + *s-'0'; return(n); } ); } if(f) { for(f=0; ofil[f]; f++) fname[f] = ofil[f]; fname[f++] = fnumber/26 + 'a'; fname[f++] = fnumber%26 + 'a'; fname[f] = '\0'; fnumber++; if(fcreat(fname, obuf) < 0) { write(2, "Cannot create output\n", 20); exit(); } f = 0; } putc(c, obuf); / strip -- strip relocation and symbols mov (sp)+,argc tst (sp)+ br loop unloop: sys unlink; s.tmp loop: dec argc bgt 1f mov exitflg,r0 sys exit 1: mov (sp)+,r4 mov r4,0f sys open; 0:..; 0 bec 1f jsr r5,mesg; ; .even br loop 1: mov r0,fi mov $'a,r1 1: movb r1,s.tmp+8 sys stat; s.tmp; buf bec 2f sys creat; s.tmp; 400 bec 1f 2: inc r1 cmp r1,$'z blos 1b jsr r5,mesg; ; .even mov $1,r0 sys exit 1: mov r0,fo clr buf mov fi,r0 sys read; buf; 512. mov r0,r3 cmp buf,magic beq 1f cmp buf,magic1 beq 1f cmp buf,magic2 beq 1f cmp buf,magic3 beq 1f jsr r5,mesg; ; .even 9: mov fi,r0 sys close mov fo,r0 sys close br unloop 1: tst buf+10 bne 1f bit $1,buf+16 bne 9b 1: mov buf+2,r2 add buf+4,r2 add $20,r2 clr r1 clr buf+10 mov $1,buf+16 / no reloc bits flag 1: mov r2,0f sub r1,0f cmp 0f,r3 blos 2f mov r3,0f 2: mov fo,r0 sys write; buf; 0:.. add 0b,r1 cmp r1,r2 bhis 1f mov fi,r0 sys read; buf; 512. mov r0,r3 bne 1b jsr r5,mesg; ; .even 1: mov fo,r0 sys close mov fi,r0 sys close mov r4,0f sys creat; 0:..; 0 / same mode as before bec 1f jsr r5,mesg; ; .even jmp unloop 1: mov r0,fo sys open; s.tmp; 0 bec 1f jsr r5,mesg; ; .even mov $1,r0 sys exit 1: mov r0,fi 1: mov fi,r0 sys read; buf; 512. mov r0,0f beq 1f mov fo,r0 sys write; buf; 0:.. br 1b 1: mov fi,r0 sys close mov fo,r0 sys close jmp unloop mesg: mov $1,exitflg movb (r5)+,ch beq 1f mov $1,r0 sys write; ch; 1 br mesg 1: inc r5 bic $1,r5 mov r4,r1 1: movb (r1)+,ch beq 1f mov $1,r0 sys write; ch; 1 br 1b 1: mov $1,r0 sys write; qnl; 1 rts r5 s.tmp: qnl: <\n> .even magic: 407 magic1: 410 magic2: 411 magic3: 405 .bss fi: .=.+2 fo: .=.+2 argc: .=.+2 buf: .=.+512. ch: .=.+2 exitflg: .=.+2 f; 512. mov r0,0f beq 1f mov fo,r0 sys write; buf; 0:.. br 1b 1: mov fi,r0 sys close mov fo,r0 sys close jmp unloop# /* * set teletype modes */ /* * tty flags */ #define HUPCL 01 #define XTABS 02 #define LCASE 04 #define ECHO 010 #define CRMOD 020 #define RAW 040 #define ODDP 0100 #define EVENP 0200 #define ANYP 0300 /* * Delay algorithms */ #define CR0 0 #define CR1 010000 #define CR2 020000 #define CR3 030000 #define NL0 0 #define NL1 000400 #define NL2 001000 #define NL3 001400 #define TAB0 0 #define TAB1 002000 #define TAB2 004000 #define TAB3 006000 #define FF0 0 #define FF1 040000 #define ALL 0177400 /* * ioctl commands */ #define FEK ('t'<<8)|0013 /* fetch erase and kill characters */ #define SEK ('t'<<8)|0014 /* set erase and kill characters */ struct { char *string; int speed; } speeds[] { "0", (0<<8)|0, "50", (1<<8)|1, "75", (2<<8)|2, "110", (3<<8)|3, "134", (4<<8)|4, "134.5",(4<<8)|4, "150", (5<<8)|5, "200", (6<<8)|6, "300", (7<<8)|7, "600", (8<<8)|8, "1200", (9<<8)|9, "1800", (10<<8)|10, "2400", (11<<8)|11, "4800", (12<<8)|12, "9600", (13<<8)|13, "exta", (14<<8)|14, "extb", (15<<8)|15, 0, }; struct { char *string; int set; int reset; } modes[] { "even", EVENP, 0, "-even", 0, EVENP, "odd", ODDP, 0, "-odd", 0, ODDP, "raw", RAW, 0, "-raw", 0, RAW, "cooked", 0, RAW, "-nl", CRMOD, 0, "nl", 0, CRMOD, "echo", ECHO, 0, "-echo", 0, ECHO, "LCASE", LCASE, 0, "lcase", LCASE, 0, "-LCASE", 0, LCASE, "-lcase", 0, LCASE, "-tabs", XTABS, 0, "tabs", 0, XTABS, "hup", HUPCL, 0, "-hup", 0, HUPCL, "cr0", CR0, CR3, "cr1", CR1, CR3, "cr2", CR2, CR3, "cr3", CR3, CR3, "tab0", TAB0, TAB3, "tab1", TAB1, TAB3, "tab2", TAB2, TAB3, "tab3", TAB3, TAB3, "nl0", NL0, NL3, "nl1", NL1, NL3, "nl2", NL2, NL3, "nl3", NL3, NL3, "ff0", FF0, FF1, "ff1", FF1, FF1, "33", CR1, ALL, "tty33", CR1, ALL, "37", FF1+CR2+TAB1+NL1, ALL, "tty37", FF1+CR2+TAB1+NL1, ALL, "05", NL2, ALL, "vt05", NL2, ALL, "tn", CR1, ALL, "tn300", CR1, ALL, "ti", CR2, ALL, "ti700", CR2, ALL, "tek", FF1, ALL, 0, }; char *arg; int mode[3]; int ek[2]; struct { char lobyte, hibyte; }; main(argc, argv) char *argv[]; { int i; gtty(1, mode); ioctl(1, FEK, ek); if(argc == 1) { prmodes(); exit(0); } while(--argc > 0) { arg = *++argv; if (eq("ek")) ek[1] = '#@'; if (eq("erase")) { ek[1].lobyte = **++argv; argc--; } if (eq("kill")) { ek[1].hibyte = **++argv; argc--; } for(i=0; speeds[i].string; i++) if(eq(speeds[i].string)) mode[0] = speeds[i].speed; for(i=0; modes[i].string; i++)  if(eq(modes[i].string)) { mode[2] =& ~modes[i].reset; mode[2] =| modes[i].set; } if(arg) printf("unknown mode: %s\n", arg); } stty(1,mode); ioctl(1, SEK, ek); } eq(string) char *string; { int i; if(!arg) return(0); i = 0; loop: if(arg[i] != string[i]) return(0); if(arg[i++] != '\0') goto loop; arg = 0; return(1); } prmodes() { register m; if(mode[0].lobyte != mode[0].hibyte) { prspeed("input speed ", mode[0].lobyte); prspeed("output speed ", mode[0].hibyte); } else prspeed("speed ", mode[0].lobyte); printf("erase = '%c'; kill = '%c'\n", ek[1].lobyte, ek[1].hibyte); m = mode[2]; if(m & 0200) printf("even "); if(m & 0100) printf("odd "); if(m & 040) printf("raw "); if(m & 020) printf("-nl "); if(m & 010) printf("echo "); if(m & 04) printf("lcase "); if(m & 02) printf("-tabs "); if(m & 01) printf("hup "); delay(m>>8, "nl"); delay(m>>10, "tab"); delay(m>>12, "cr"); delay((m>>14)&1, "ff"); delay((m>>15)&1, "bs"); printf("\n"); } delay(m, s) char *s; { if(m =& 3) printf("%s%d ", s, m); } int speed[] { 0,50,75,110,134,150,200,300,600,1200,1800,2400,4800,9600,0,0 }; prspeed(c, s) { printf("%s%d baud\n", c, speed[s]); } putchar(c) { write(2, &c, 1); } if(m & 020) printf("-nl "); if(m & 010) printf("echo "); if(m & 04) printf("lcase "); if(m & 02) printf("-tabs "); if(m & 01) printf("hup "); delay(m>>8, "nl"); delay(m>>10, "tab"); delay(m>>12, "cr"); delay((m>>14)&1, "ff"); delay((m>>15)&1, "bs"); printf("\n"); } delay(m, s) char *s; {/* su -- become super-user */ char password[100]; char pwbuf[100]; int ttybuf[3]; main() { register char *p, *q; extern fin; if(getpw(0, pwbuf)) goto badpw; (&fin)[1] = 0; p = pwbuf; while(*p != ':') if(*p++ == '\0') goto badpw; if(*++p == ':') goto ok; gtty(0, ttybuf); ttybuf[2] =& ~010; stty(0, ttybuf); printf("password: "); q = password; while((*q = getchar()) != '\n') if(*q++ == '\0') return; *q = '\0'; ttybuf[2] =| 010; stty(0, ttybuf); printf("\n"); q = crypt(password); while(*q++ == *p++); if(*--q == '\0' && *--p == ':') goto ok; goto error; badpw: printf("bad password file\n"); ok: setuid(0); execl("/bin/sh", "+", 0); printf("cannot execute shell\n"); error: printf("sorry\n"); } goto badpw; if(*++p == ':') goto ok; gtty(0, ttybuf); ttybuf[2] =& ~010; stty(0, ttybuf); printf("password: "); q = password; while((*q = getchar()) != '\n') if(*q++ == '\0') return; *q = '\0'; ttybuf[2] =| 010; stty(0, ttybuf); printf("\n"); q = crypt(password/ sum -- check sum file mov (sp)+,r3 tst (sp)+ loop: dec r3 bgt 1f sys exit 1: mov (sp)+,0f sys open; 0:..; 0 bec 3f mov $1,r0 sys write; 1f; 2f-1f br loop 1: 2: .even 3: mov r0,r1 clr r5 1: mov r1,r0 sys read; buf; 512. bes err tst r0 beq print inc bcnt mov $buf,r2 2: movb (r2)+,r4 add r4,r5 adc r5 sob r0,2b br 1b err: mov $1,r0 sys write; 1f; 2 print: jsr pc,decml mov $1,r0 sys write; bl; 1 mov bcnt,r5 jsr pc,decml mov $1,r0 sys write; nl; 1 mov r1,r0 sys close br loop 1: nl: <\n> bl: < > .even decml: mov r0,-(sp) mov r1,-(sp) mov r5,r1 jsr pc,1f mov (sp)+,r1 mov (sp)+,r0 rts pc 1: clr r0 dvd $10.,r0 mov r1,-(sp) mov r0,r1 beq 1f jsr pc,1b 1: mov (sp)+,ch add $'0,ch mov $1,r0 sys write; ch; 1 rts pc .bss ch: .=.+2 bcnt: .=.+2 buf: .=.+512. add r4,r5 adc r5 sob r0,2b br 1b err: mov $1,r0 sys write; 1f; 2 print: jsr pc,decml mov $1,r0 sys write; bl; 1 mov bcnt,r5 jsr pc,decml mov $1,r0 sys write; nl; 1 mov r1,r0 sys closemain() { sync(); } <\n> bl: < > .even decml: mov r0,-(sp) mov r1,-(sp) mov r5,r1 jsr pc,1f mov (sp)+,r1 mov (sp)+,r0 rts pc 1: clr r0 dvd $10.,r0 mov r1,-(sp) mov r0,r1 beq 1f jsr pc,1b 1: mov (sp)+,ch add $'0,ch mov $1,r0 sys write; ch; 1 rts pc .bss ch: .=.+2 bcnt: .=.+2 buf: .=.+512. add r4,r5 adc r5 sob r0,2b br 1b err: mov $1,r0 sys write; 1f; 2 print: jsr pc,decml mov $1,r0 sys write; bl; 1 mov bcnt,r5 jsr pc,decml mov $1,r0 sys write; nl; 1 mov r1,r0 sys close/* time command */ char *name "//usr/bin/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; int errno; long lmuls(), ldivs(); main(argc, argv) char **argv; { struct { long user; long sys; long childuser; long childsys; } buffer; char status[2]; register p; register i; long before, after; if(argc<=1) return(0); time(&before); p = fork(); if(p == -1) { prints("Try again.\n"); return(1); } if(p == 0) { argv[argc] = 0; for(i=0; name[i+10] = argv[1][i]; i++) ; for(i = 10; i >= 0; i =- 5) { errno = 0; execv(&name[i], &argv[1]); if(errno == 8) { argv[0] = "/bin/sh"; argv[1] = &name[i]; execv(argv[0], argv); exit(1); } } prints(argv[1]); prints(" not found."); exit(1); } signal(2, 1); signal(3, 1); while(wait(status) != p); time(&after); if(status[0] != '\0') prints("Command terminated abnormally.\n"); times(&buffer); prints("\n"); printt("real", lmuls(after-before, 60)); printt("user", buffer.childuser); printt("sys ", buffer.childsys); exit(status[1]); } char quant[] { 6, 10, 10, 6, 10, 6, 10, 10, 10 }; char *pad "000 "; char *sep "\0\0.\0:\0:\0\0"; char *nsep "\0\0.\0 \0 \0\0"; printt(s, a) char *s; long a; { char digit[9]; long b; register i; int c; int nonzero; for(i=0; i<9; i++) { b = ldivs(a, quant[i]); digit[i] = a - lmuls(b, quant[i]); a = b; } prints(s); nonzero = 0; while(--i>0) { c = digit[i]!=0 ? digit[i]+'0': nonzero ? '0': pad[i]; prints(&c); nonzero =| digit[i]; c = nonzero?sep[i]:nsep[i];  prints(&c); } prints("\n"); } prints(s) char *s; { while(*s) write(2, s++, 1); } /* long=long*short, long=long/short, to avoid floating point */ struct { int hi, lo; }; long lmuls(l, s) long l; { long p; if(l.lo<0) l.hi++; p.hi = l.hi*s; p.lo = l.lo*s; p.hi =+ hmul(l.lo, s); return(p); } long ldivs(l, s) long l; { long q; long d; long mone; mone.hi = 0; mone.lo = 32768; d = lmuls(mone, s); for(q=0; l>=d; q=+mone) l =- d; q =+ ldiv(l.hi, l.lo, s); return(q); } zero?sep[i]:nsep[i]; int dflag 0; int sflag 0; int cflag 0; int save 0; char code[256]; char squeez[256]; char vect[256]; struct string { int last, max, rep; char *p; } string1, string2; main(argc,argv) char **argv; { int i, j; int c, d; char *compl; extern fin, fout; string1.last = string2.last = 0; string1.max = string2.max = 0; string1.rep = string2.rep = 0; string1.p = string2.p = ""; if(--argc>0) { argv++; if(*argv[0]=='-') { while(*++argv[0]) switch(*argv[0]) { case 'c': cflag++; continue; case 'd': dflag++; continue; case 's': sflag++; continue; } argc--; argv++; } } if(argc>0) string1.p = argv[0]; if(argc>1) string2.p = argv[1]; for(i=0; i<256; i++) code[i] = vect[i] = 0; if(cflag) { while(c = next(&string1)) vect[c&0377] = 1; j = 0; for(i=1; i<256; i++) if(vect[i]==0) vect[j++] = i; vect[j] = 0; compl = vect; } for(i=0; i<256; i++) squeez[i] = 0; for(;;){ if(cflag) c = *compl++; else c = next(&string1); if(c==0) break; d = next(&string2); if(d==0) d = c; code[c&0377] = d; squeez[d&0377] = 1; } while(d = next(&string2)) squeez[d&0377] = 1; squeez[0] = 1; for(i=0;i<256;i++) { if(code[i]==0) code[i] = i; else if(dflag) code[i] = 0; } fin = dup(0); fout = dup(1); close(0); close(1); while(c = getchar()) if(c = code[c&0377]&0377) if(!sflag || c!=save || !squeez[c&0377]) putchar(save = c); flush(); } next(s) struct string *s; { int a, b, c, n; int base; if(--s->rep > 0) return(s->last); if(s->last < s->max) return(++s->last); if(*s->p=='[') { nextc(s); s->last = a = nextc(s); s->max = 0; switch(nextc(s)) { case '-': b = nextc(s); if(bp++!=']') goto error; s->max = b; return(a); case '*': base = (*s->p=='0')?8:10; n = 0; while((c = *s->p)>='0' && c<'0'+base) { n = base*n + c - '0'; s->p++; } if(*s->p++!=']') goto error; if(n==0) n = 1000; s->rep = n; return(a); default: error: write(1,"Bad string\n",11);  exit(); } } return(nextc(s)); } nextc(s) struct string *s; { int c, i, n; c = *s->p++; if(c=='\\') { i = n = 0; while(i<3 && (c = *s->p)>='0' && c<='7') { n = n*8 + c - '0'; i++; s->p++; } if(i>0) c = n; else c = *s->p++; } if(c==0) *--s->p = 0; return(c&0377); } le((c = *s->p)>='0' && c<'0'+base) { n = base*n + c - '0'; s->p++; } if(*s->p++!=']') goto error; if(n==0) n = 1000; s->rep = n; return(a); default: error: write(1,"Bad string\n",11); # #define SINGLE 7 #define REBOOT ~7 #define SHUP 1 #define SINT 2 #define SBUS 10 #define SSEG 11 #define EGOOD 0 #define EBAD 1 main(argc,argv) char **argv; { register i,pid; ++argv; pid = 1; if((*argv)[1] != 0){ printf("Illegal argument\n"); exit(EBAD); } switch(**argv){ case 'Q': /*Query lines file*/ kill(pid,SHUP); exit(EGOOD); case 'R': /*Reboot signal*/ if(getcsw() == REBOOT) kill(pid,SBUS); else{ printf("Illegal switch settings\n"); exit(EBAD); } exit(EGOOD); case 'S': /*Single signal*/ if(getcsw() == SINGLE) kill(pid,SBUS); else{ printf("Illegal switch settings\n"); exit(EBAD); } exit(EGOOD); case 'a': /*Asynchronous stimuli*/ case 'b': case 'c': kill(pid,(**argv - 'a' + SSEG)); exit(EGOOD); default : i = **argv - '0'; if(i>=0 && i<= 6) kill(pid,i+SINT); else{ printf("Illegal argument\n"); exit(EBAD); } } exit(EGOOD); } printf("Illegal switch settings\n"); exit(EBAD); }# define NOFLOAT 1 char w2006[24]; flg 0; char realwd[26]; char *wd {&realwd[1]}; /* int etext; int rathole[1000]; */ int neng; int npr; int table[2]; int tab1[26]; int tab2[730]; char tab3[19684]; # ifndef NOFLOAT int logtab[256]; float inctab[256]; # endif # ifdef NOFLOAT extern int logtab[]; extern int inctab[]; # endif char nwd[26]; mask 0377; int tot; int wtot; char *buf[3]; file[3]; ptr[3]; char *name[4]; bsp[768]; main(argc,argv) int argc; char *argv[]; { char let,lt; auto arg,num,t,sw,i,j,k,l,m,salt,er,c; int unl(); int junk; /* monitor(&main, &etext, rathole, 1000); */ if(--argc < 1){printf("arg count\n"); exit(); } buf[0] = bsp; buf[1] = bsp + 0400; buf[2] = bsp + 01000; ptr[0] = 0; ptr[1] = 0; ptr[2] = 1; arg = 1; while(argv[arg][0] == '-') { switch(argv[arg][1]) { default: printf("Unrecognizable argument: %c\n",argv[arg][1]); exit(); case 0: case 'n': neng++; break; case '1': npr++; } arg++; if(--argc < 1) { printf("arg count\n"); exit(); } } if(!neng) { salt = open("/usr/lib/salt",0); er = read(salt,table,4); if(er != 4)err("read salt"); er = read(salt,tab1,52); if(er != 52) err("read salt"); er = read(salt,tab2,1460); if(er != 1460) err("read salt"); er = read(salt,tab3,19684); if(er != 19684)err("read salt"); close(salt); } signal(2,unl); name[0] = "/tmp/ttmpa1"; name[1] = "/tmp/ttmpa2"; name[2] = "/tmp/ttmpa3"; name[3] = "/tmp/ttmpa4"; topen: file[0] = open(name[0],1); if(file[0] > 0){ close(file[0]); j = -1; while(++j < 4)name[j][9]++; if(name[0][9] == 'z')err("creat tmp file"); goto topen; } j = 2; while(j--)file[j] = creat(name[j],0666); while(argc--){ file[2] = open(argv[arg++],0); if(file[2] < 0)err("open input file"); while((j = wdval(2)) != 0){ put(dfile(nwd[0]),nwd,j+1); k = -1; l = 0; m = 1; table[0] = incr(table[0]); while(m <= j+1){ c = 27*wd[k++] + wd[l++]; tab2[c] = incr(tab2[c]); c = 27*c + wd[m++]; tab3[c] = incr(tab3[c] & 0377); } c = 27*wd[k] + wd[l]; tab2[c] = incr(tab2[c]); } done1: close(file[2]); } /* junk = creat("junk\0",0666); write(junk,table,4+52+1460+19684); close(junk); */ j = 2; while(j--){flsh(j,0); close(file[j]); } j = 2; while(j--){ sw = fork(); if(sw == 0){execl("/bin/sort","sort", "-o", name[j],name[j],0); err("sort"); } if(sw < 0)err("fork"); er = wait(); if(er != sw)err("probs"); } j = -1; while(++j < 2){ sw = fork(); if(sw == 0){execl("/bin/uniq","uniq",name[j],name[j+2]); err("uniq"); } if(sw < 0)err("fork"); er = wait(); if(er != sw)err("prob"); } file[0] = creat(name[0],0666); if(file[0] < 0)err("creat tmp"); file[1] = open("/usr/lib/w2006",0); if(file[1] < 0)err("open w2006"); ptr[1] = 1; j = -1; while((w2006[++j] = get(1)) != '\n'); lt = 1; while(++lt < 4){ file[2] = open(name[lt],0); if(file[2] < 0)err("open tmp"); ptr[2] = 1; getw: k = -1; while((wd[++k] = get(2)) != '\n')if(wd[k] == 0)goto done; scan: i = -1; l = 0; while(++i <= k){ if(wd[i] < w2006[l]){ put(0,wd,k); goto getw; } if(wd[i] > w2006[l]){ l = -1; while((w2006[++l] = get(1)) != '\n') if(w2006[l] == 0)goto fin; goto scan; } l++; } goto getw; fin: put(0,wd,k); k = -1; while((wd[++k] = get(2)) != 0){ if(wd[k] == '\n'){ put(0,wd,k); k = -1; }} done: close(file[2]); unlink(name[lt]); } flsh(0,0); close(file[1]); close(file[0]); ptr[1] = 1; file[1] = open(name[0],0); if(file[1] < 0)err("open tmp "); file[0] = creat(name[1],0666); if(file[0] < 0)err("create tmp"); while((j = wdval(1)) != 0){ wtot = 0; flg = 0; k = -1; l = 0; m = 1; while(m <= j+1){ tot = 0; c = wd[k++]*27 + wd[l++]; digram(c); digram(wd[k]*27 + wd[l]); tot =>> 1; c = c*27 + wd[m++]; trigram(c); if(tot > wtot) wtot = tot; } if(wtot < 0) wtot = 0; t = conf(wtot,3,wd); wd[3] = ' '; put(0,wd,3); put(0,nwd,j+1); } flsh(0,0); close(file[1]); close(file[0]); /* monitor(0); goto unl; */ sw = fork(); if(sw == 0){execl("/bin/sort","sort","+0nr", "+1","-o",name[1],name[1] ,0); err("sort"); } if(sw < 0)err("fork"); er = wait(); if(er != sw)err("prob"); sw = fork(); if(sw == 0){ if(npr) { execl("/bin/cat","cat",name[1],0); } else { execl("/bin/pr","pr","-3", "-h", "Possible typo's and spelling errors",name[1],0); err("pr"); } } if(sw < 0)err("fork"); er = wait(); if(er != sw)err("prob"); unl(); } unl() { int j; j = 2; while(j--)unlink(name[j]); exit(); } trigram(c) int c; { int t; t = logtab[tab3[c]&0377]; tot =- t; return; } digram(c) int c; { int t; t = logtab[tab2[c]]; tot =+ t; return; } dfile(c) char c; { if(c >= 'a' && c <= 'k')return(0); return(1); } err(c) char c[];{ auto j; printf("cannot %s\n",c); j = 4; while(j--)unlink(name[j]); exit(); } get(ifile) int ifile;{ static char *ibuf[10]; if(--ptr[ifile]){ return(*ibuf[ifile]++);} if(ptr[ifile] = read(file[ifile],buf[ifile],512)){ if(ptr[ifile] < 0)goto prob; ibuf[ifile] = buf[ifile]; return(*ibuf[ifile]++); } ptr[ifile] = 1; return(0); prob: ptr[ifile] = 1; printf("read error\n"); return(0); } put(ofile,s,optr) char s[]; {auto i; while(optr-- >= 0) buf[ofile][(ptr[ofile] < 512)?ptr[ofile]++:flsh(ofile,1)] = *s++; return; } flsh(ofile,i){auto error; error = write(file[ofile],buf[ofile],ptr[ofile]); if(error < 0)goto prob; ptr[ofile] = i; return(0); prob: printf("write error on t.%d\n",file); exit(); } wdval(wfile) int wfile; { static let,wflg; auto j; beg: j = -1; if(wflg == 1){wflg = 0; goto st; } while((let = get(wfile)) != '\n'){ if(let == 0)return(0); st: if(let == '%' && j != -1)goto cont; if(let == '-'){ if((let = get(wfile)) == '\n'){ while((let = get(wfile)) == '\n'); goto st; } wflg = 1; goto ret; } if(let == 047){if(j < 1)goto ret; goto cont; } if(let < 'A')goto ret; if(let <= 'Z'){ wd[++j] = let - 0100; nwd[j] = let + ' '; goto cont; } if(let < 'a' || let > 'z')goto ret; wd[++j] = let - 0140; nwd[j] = let; cont: ; } while(((let = get(wfile)) == '.') || (let == 047)){ while((let = get(wfile)) != '\n'); } wflg = 1; ret: if(j < 1)goto beg; nwd[j+1] = '\n'; wd[j+1] = 0; return(j); } conf(n,width,cbuf) char cbuf[]; { auto i,a; i = width; while(i--)cbuf[i] = ' '; cbuf[(a = n/10)?conf(a,--width,cbuf):--width] = n%10 + '0'; return(++width); } # ifndef NOFLOAT incr(gork) int gork; { float log(), exp(), pow(); int static first; int ii; if(first == 0){ inctab[0] = 1; logtab[0] = -10; for(ii=1; ii<256; ii++){ inctab[ii] = exp(-ii/30.497); logtab[ii] = log(30.*pow(1.0333,ii+0.) - 30.) + .5; } logtab[1] = -10; first = 1; } if(inctab[gork] > rand()/32768.) gork++; if(gork > 255) gork = 255; return(gork); } # endif # ifdef NOFLOAT int inctab[256] { 32767,31710,30688,29698,28740,27812,26915,26047,25207,24394, 23607,22845,22108,21395,20705,20037,19391,18765,18160,17574, 17007,16458,15927,15414,14916,14435,13969,13519,13083,12661, 12252,11857,11474,11104,10746,10399,10064, 9739, 9425, 9121, 8827, 8542, 8266, 8000, 7742, 7492, 7250, 7016, 6790, 6571, 6359, 6154, 5955, 5763, 5577, 5397, 5223, 5055, 4892, 4734, 4581, 4433, 4290, 4152, 4018, 3888, 3763, 3641, 3524, 3410, 3300, 3194, 3091, 2991, 2894, 2801, 2711, 2623, 2539, 2457, 2377, 2301, 2227, 2155, 2085, 2018, 1953, 1890, 1829, 1770, 1713, 1657, 1604, 1552, 1502, 1454, 1407, 1361, 1317, 1275, 1234, 1194, 1155, 1118, 1082, 1047, 1013, 981, 949, 918, 889, 860, 832, 805, 779, 754, 730, 706, 684, 661, 640, 619, 599, 580, 561, 543, 526, 509, 492, 476, 461, 446, 432, 418, 404, 391, 379, 366, 355, 343, 332, 321, 311, 301, 291, 282, 273, 264, 255, 247, 239, 231, 224, 217, 210, 203, 196, 190, 184, 178, 172, 167, 161, 156, 151, 146, 141, 137, 132, 128, 124, 120, 116, 112, 109, 105, 102, 98, 95, 92, 89, 86, 83, 81, 78, 76, 73, 71, 68, 66, 64, 62, 60, 58, 56, 54, 53, 51, 49, 48, 46, 44, 43, 42, 40, 39, 38, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 24, 23, 22, 21, 21, 20, 19, 19, 18, 17, 17, 16, 16, 15, 15, 14, 14, 13, 13, 12, 12, 12, 11, 11, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 7, 7}; int logtab[256] { -10,-10, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 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, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12}; incr(gork) int gork; { if(inctab[gork] > rand()) gork++; if(gork > 255) gork = 255; return(gork); } # endif 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, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10#define NMOUNT 16 #define NAMSIZ 32 struct mtab { char file[NAMSIZ]; char spec[NAMSIZ]; } mtab[NMOUNT]; main(argc, argv) char **argv; { register struct mtab *mp; register char *p1, *p2; int mf; mf = open("/etc/mtab", 0); read(mf, mtab, NMOUNT*2*NAMSIZ); if(argc != 2) { printf("arg count\n"); return; } if (umount(argv[1]) < 0) { perror("umount"); return; } p1 = argv[1]; while(*p1++) ; p1--; while(*--p1 == '/') *p1 = '\0'; while(p1 > argv[1] && *--p1 != '/') ; if(*p1 == '/')  p1++; argv[1] = p1; for (mp = mtab; mp < &mtab[NMOUNT]; mp++) { p1 = argv[1]; p2 = &mp->spec[0]; while (*p1++ == *p2) if (*p2++ == 0) { for (p1 = mp->file; p1 < &mp->file[NAMSIZ*2];) *p1++ = 0; mp = &mtab[NMOUNT]; while ((--mp)->file[0] == 0); mf = creat("/etc/mtab", 0644); write(mf, mtab, (mp-mtab+1)*2*NAMSIZ); return; } } printf("%s not in mount table\n", argv[1]); } while(*--p1 == '/') *p1 = '\0'; while(p1 > argv[1] && *--p1 != '/') ; if(*p1 == '/') fields 0; letters 0; linec; mode; uniq; main(argc, argv) int argc; char *argv[]; { extern fin, fout; int f; static char b1[1000], b2[1000]; loop: if(argc > 1) { if(*argv[1] == '-') { if(argv[1][1] <= '9') fields = conv(&argv[1][1]); else mode = argv[1][1]; argc--; argv++; goto loop; } if(*argv[1] == '+') { letters = conv(&argv[1][1]); argc--; argv++; goto loop; } f = open(argv[1], 0); if(f < 0) { printf("cannot open %s\n", argv[1]); exit(); } fin = f; } else fin = dup(0); if(argc > 2) { f = creat(argv[2], 0666); if(f < 0) { printf("cannot create %s\n", argv[2]); exit(); } fout = f; } else fout = dup(1); close(0); close(1); gline(b1); l1: linec++; if(gline(b2)) { pline(b1); flush(); exit(); } if(equal(b1, b2)) goto l1; pline(b1); linec = 0; l2: linec++; if(gline(b1)) { pline(b2); flush(); exit(); } if(equal(b1, b2)) goto l2; pline(b2); linec = 0; goto l1; } gline(buf) char buf[]; { int c; while((c = getchar()) != '\n') { if(c == '\0') return(1); *buf++ = c; } *buf = 0; return(0); } pline(buf) char buf[]; { int c; switch(mode) { case 'u': if(uniq) {; uniq = 0; return; } break; case 'd': if(uniq) break; return; case 'c': printf("%4d ", linec); } uniq = 0; while((c = *buf++) != 0) putchar(c); putchar('\n'); } equal(b1, b2) char b1[], b2[]; { char *skip(); int c; b1 = skip(b1); b2 = skip(b2); while((c = *b1++) != 0) if(c != *b2++) return(0); if(*b2 != 0) return(0); uniq++; return(1); } char * skip(s) char *s; { int nf, nl; nf = nl = 0; while(nf++ < fields) { while(*s==' ' || *s=='\t') s++; while( !(*s==' ' || *s=='\t') ) if(*s == 0) return(s); else s++; } while(nl++ < letters) if(*s == 0) return(s); else s++; return(s); } conv(s) char *s; { int d, n; n = 0; for(;;) { d = *s++ - '0'; if(0>d || d>9) break; n = n*10 + d; } return(n); } = skip(b2); while((c = *b1++) != 0) if(c != *b2++) return(0); if(*b2 != 0 sys fork br 1f sys exit 1: sys sync mov $30.,r0 sys sleep br 1b sleep = 35. sync = 36. hile(nf++ < fields) { while(*s==' ' || *s=='\t') s++; while( !(*s==' ' || *s=='\t') ) if(*s == 0) return(s); else s++; } while(nl++ < letters) if(*s == 0) return(s); else s++; return(s); } conv(s) char *s; { int d, n; n = 0; for(;;) { d = *s++ - '0'; if(0>d || d>9) break; n = n*10 + d; } return(n); } = skip(b2); while((c = *b1++) != 0) if(c != *b2++) return(0); if(*b2 != 0ability able about above absence abstract academic accept acceptable accepted accepts access accessed accessible accomplished accordance according accordingly account accuracy accurately achieve achieved achievement across act acting action actions activated activates activation active activities activity actual actually actuated adapted add added adding addition additional additions additive address addressed adequate adjacent administration adopted advance advantage advantageously affairs affect affected affects aforementioned after afternoon again against age agencies agency ago agreed agreement ahead aid air algebraic algol algorithm algorithms all allow allowed allows almost alone along already also alter altered alternate alternative alternatively alternatives although always america american among amount amplifier amplitude an analog analogous analyses analysis analyze and angle animal announced annual anode anodes another answer answered answers any anyone anything apart apparatus apparent apparently appeal appear appearance appeared appearing appears application applications applied applies apply applying approach appropriate appropriately approximate approximated approximately approximation april arbitrary are area areas argued argument arguments arise arises arithmetic around arrangement arrangements array arrays arrive arriving art article arts as aside ask asked asking aspect aspects assign assigned assignment assistance associated association assume assumed assumes assuming assumption asymmetric at atmosphere atom attack attempt attempts attention attitude attorney attractive audio august author authority automatic available average avoid aware away axes axis back background bad balance ball bandwidth bank bar base based basic basis be bear became because become becomes becoming been before began begin beginning begins behavior behind being belief believe believed bell below beneath benefit bent besides best better between beyond bill binary biometrika bit bits black block blocks blue board body book books both bottom bought bound boundaries boundary bounds box branch branches break breakdown brief bring broad broken brought brown bubble budget build building buildings built burning bus buses business busy but buy by cable calculation california call called calling calls came can cannot capabilities capability capable capacity capital card care career careful carefully carried carries carroll carry carrying case cases cathode cathodes catholic caught cause caused causes causing cell cells center centered central century certain certainly chain chairman chance chang change changed changes channel channels chapter character characteristic characteristics characters charge charged charging chart check checked chemical chief children choice choices choose chosen circle circuit circuitry circuits circumstances citizens city civil claim claims class classes classified clean clear clearly clock close closed closely closer closest closure cluster clustering clusterings clusters cm code coding coefficient coefficients coffee cold collection college color column columns combination combinations combined combining come comes coming command comment comments commerce commercial committee common communicates communication communications communist community compact companies company comparable compared comparison compensate compensation competent competition compilers compiling complement complete completed completely completion complex complexity complicated component components composite composition comprise comprises comprising computation computational computations compute computed computer computing conceived concentrated concentration concept concepts concern concerned concerning conclude conclusion conclusions condition conditional conditions conductivity conductor conductors conference confidence configuration configurations congruent connected connecting connection connections connects consequently consider considerable consideration considerations considered considering consistent consisting consists constant constants constrained constraint constraints construct constructed constructing construction contact contacts contain contained containing contains contents continue continued continues continuing continuity continuous contract contrast control controllable controlled controlling controls convenient convention conventional conventions conversely conversion convert converted converter converting cooperation coordinate coordinates core corporation correct correctly correlation correspond corresponding corresponds cosines cost costs could council count counted counter counting countries country counts couple coupled coupling course courses court cover covered create created credit crisis criterion critical crop cross crossovers cubic culture current currently curve curves cut cutoff cutting cycle cycles daily dallas damage danger dark data date day days dead deal debugging december decide decided decision decisions declared decoded decoder decoding decomposition decrease decreases decreasing deep defect defects define defined defines defining definite definition definitions degree delay delayed delays delete demand density department departures depend dependent depending depends depicted depth derived deriving descendant descendants describe described describing description design designated designed designs desirable desire desired despite destination detail detailed details detected detection detects determine determined determines determining develop developed developing development deviation deviations device devices diagonal diagram diagrams dial diameter dictates dictionary did die dielectric difference differences different differential difficult difficulties difficulty diffusion digit digital digits dimension dimensions direct directed direction directions directly director discharge discharges disclosed discloses disclosure disconnected discovered discrepancy discrete discuss discussed discussion display displays disposed dissimilarities dissimilarity distance distances distinct distinction distinguish distortions distribution divided division do document documented does doing dollars domain dominant done doped dotted double doubt down dr draw drawing drawn drew drink drive driving drop dropped due duration during dust duty dynamic each earlier early earth ease easier easily east easy economic economically economy edge edges editing editor education educational effect effective effectively effects efficiency efficient efficiently effort efforts eight either electric electrical electrode electrodes electronic electrons element elements eliminate eliminated else embedded embodiment embodiments emotional emphasis employed employees empty enable enabled enclosed encoding encountered encourage end ends energy engineering english enough enter entered entire entirely entities entitled entries envelope environment epitaxial equal equally equals equation equations equilibrium equipment equipped equivalent equivalently error errors escape especially essential essentially establish established establishing estimated et etc evaluated even evening event events ever every everybody everyone everything evidence evidenced evident evil exact exactly examine examined example examples exceeds excellent except exception exchange exclusive executed executing execution exercise exhibit exist existence existing exists exit expect expected expects expense expensive experience experiment experimental experiments experts explain explained explanation explicit explicitly exponential exposed express expressed expression extend extended extensive extent external extinguished extra extreme extremely fabricated face faces facilities fact factor factors facts faculty failed failure fair fairly faith fall falls false familiar families family far fashion fast faster favor fear feasible feature features february feed feedback feel feeling feet felt few fewer field fields fifteen fifth fig figs figure figures file filed files filled filling film filter filtering final finally financial find finding finds fine finished finite fire firm first fiscal fit fitting five fixed flexibility flip floor flop flops flow follow followed following follows food foot for force forced forces foregoing foreign forest form formal format formed former forming forms formula formulation forth fortran forward found four fourth fraction frame frames free freedom french frequencies frequency frequently fresh friend friendly from front full fully function functional functions fund fundamental funds furnish furnishes further furthermore future gain gap gas gaseous gate gates gating gave general generality generalization generalized generally generate generated generates generating generation generator geometries geometry german germany get gets getting give given gives giving glass global glow go goal goes going gone good goods government governments grant granted graph graphic great greater greatest greatly green gross ground grounded grounds group grouped grouping groups grow growing growth guaranteed guarantees guard guess guests had hair half hall hand handle handling hands happen happened hard hardly hardware has have having he head health heard heat heavily heavy held help helped hence here herein hereinafter hidden hierarchical high higher highest highly hill him himself his historical history hold holding hole home hook hope horizontal hospital hot hour hours house housing how however human hundred idea ideal ideas identical identification identified identify identity idle if illustrate illustrated illustrating illustration illustrative image immediate immediately impact implement implementation implemented implicitly implied implies imply importance important impossible improve improved improvement impurities impurity in inches include included includes including incoming incorporated increase increased increases increasing increment indeed independence independent index india indicate indicated indicates indicating indicative individual individuals industrial industry inequality influence information informed initial initialize initially initiate initiated input inputs inserted inside instability install instance instances instantaneously instead instruction instructions insurance integer integers integral integrated intellectual intended intensity intent inter interaction interactions interchange interconnected interconnection interest interested interesting interests interface interior intermediate internal international interpreted interstage interval intervals into introduced introduction invention inverse inverted inverter investigation invites involve involved involves involving ion ions is issue issued issues it items its itself james january jersey job jobs john joined jointly jr judge judged judgment judicious july jump june just justice justification justify keep keeping kennedy kept key kill kind kinds knew know knowledge known knows labeled labelled labels laboratories laboratory lack lag laid land language languages large larger largest last late later latter law laws lay layer layers layout lead leader leaders leadership leading leads learn learned learning least leave leaving led left leftmost legal length less let letter letters level levels liability liable liberal library lie lies life light like likely limit limitations limited limiting limits line linear linearly lines link links list listing lists literature little live lived load loaded loading local locally located location locations log logic logical long longer longest look looked looking looks loop loops lose loss losses lost lot low lower lowest machine machinery machines made magnetic magnitude main maintain maintained maintenance major majority make makes making man management manager manner manual manufacturer manufacturers manufacturing many mapping march margins mark marked market mask masking mass master match matched matches matching material materials mathematical mathematically matrices matrix matter matters maximum may me mean meaning meaningful means meant measure measured measurement measurements measures measuring mechanical mechanism medical meet meeting meetings member members membership memory men mentioned merely merged merging message met metal metallization method methods metric middle might miles military million mind minds minimal minimize minimizes minimizing minimum minister minor minutes missing mistakes mixture mode model models modern modes modification modifications modified modular moment money monotone monotonic monotonically month months moon moral more moreover morgan morning most motor mounted move moved moves moving much multi multidimensional multiple multiplication multiplier multipliers multistage multivariate murder murray must mutually my name named names narrow nation national nations natural naturally nature near nearer nearest nearly necessarily necessary need needed needs negative neighboring neither net network neutral never nevertheless new news next nice night nine no nobody node nodes noise non none nonlinear nor normal normalized normally north not notation note noted notes nothing notice noting novel november now nuclear number numbered numbers numeric numerical object objective objects observation observe observed obtain obtained obvious obviously occasion occupied occupy occur occurred occurrence occurrences occurring occurs october odd of off offer offered office officer officers official officials often oil old omitted on once one ones only onto open opened opening operate operated operates operating operation operations opinion opportunities opportunity opposite optimal optimization optimum options or order ordered ordering orders ordinary organization organizations organized orientation oriented origin original originally orthogonal other others otherwise ought our ourselves out outline outlined output outputs outside over overall overlap own page pain pair pairs paper paragraph parallel parameter parameters part partial particular particularly parties partitioning parts party pass passed passes passing past patent path paths patient pattern patterns pay peak people per perfect perform performance performed performing performs perhaps period periodically peripheral permanent permit permits permitted person personal personnel persons pertinent phase phases phenomena philosophy physical pick picked pickup picture piece pieces place placed places placing plan planar plane planned planning plans plant plants plausible play played playing plays please plotted plurality plus point pointed pointer points polarity police policies policy political polynomial pool poor popular population portion position positive possibility possible possibly post potential power powerful practical practice preceding precise precision predetermined predicted prepared presence present presented presents press pressure presumably pretty prevent prevents previous previously price prices primarily primary prime priming principal principle principles print printed prints prior priority privacy private probability probably problem problems proc procedure procedures process processed processes processing processor produce produced produces producing product production products professional professor program programmer programmers programming programs progress project projections projects proof propagate propagated propagating propagation proper properly properties property proportional proposal proposals proposed protect protection proved provide provided provides providing provision public publication published pulse pulses pure purely purpose purposes put puts quality quantization question questions quick quickly quiet quite radio raised random randomly range rank rapid rapidly rare rate rated rates rather ratio rational reach reached reaction read readable reader readers readily reading ready real reality realize realized realizing really rear reason reasonable reasonably reasons receive received receives receiving recent recently recognize recognized record records recover rectangular recursive recursively red reduce reduced reduces reduction refer reference references referred refers reflect refused regard regarded regarding regardless region regions register registers regression regular rejected relate related relates relating relation relations relationship relative relatively relay release released relevant reliability relief remain remainder remained remaining remains remembered remote remove removed removes repeat repeated repeatedly replaced replaces report reported reports represent representation representations representative represented representing represents request require required requirement requirements requires requiring requisite research reserved reset resetting resistance resistivity resistor resistors resolution resources respect respective respectively response responsibility responsible responsive rest restored restrict restricted result resulting results return returned returns reverse review reviewed rich right rights rise risk roads role roles room root roots rose rotation roughly round rounded route routed routine routines routing routings row rows rule rules run running runs safe said sales same sample samples sampling san satisfied satisfies satisfy save say saying says scalar scale scaled scaling scan schematically school schools science sciences scientific scope sea search second secondary seconds secret section sections security see seeing seek seeking seem seemed seems seen segment segments seldom select selected selection selectively self semiconductor send sense sensitive sensitivity sent separate separation september sequence sequences sequentially serial series serious serve served serves service serviced services serving set sets setting seven several severe shall shape share sharp sheet shift shifting shifts ship shop short shot should show showed showing shown shows side sides sign signal signals significance significant significantly similar similarly simple simpler simplest simplicity simply simultaneously since single sit site situation situations six size sizes skilled slightly slot slots slow slowly small smaller smallest snow so social society soft software solid solution solutions solved some someone something sometimes somewhat somewhere son soon sophisticated sort sought sound source sources space spaced spaces spacing spatial speaking special specific specifically specifications specified specify specifying speech speed spent spirit spite splitting spoke spot spread spring square squares stable staff stage stages stand standard standards standing stands start started starting state stated statement statements states static station stations statistical statistically status stay steady step steps still stimuli stimulus stop stopped storage store stored stores straight straightforward strange strategy stream street streets strength stress strict strong strongly structure structures struggle student students studied studies study style subject subjected subjects submitted subroutines subsequent subsequently subset subsets substantial substantially substituting substitution substrate succeeding success successful successive successively such suddenly sufficient sufficiently suggest suggested suggests suitable suitably sum summarize summary summing supervision supervisory supplied supplies supply support supporting suppose supposed sure surface surprised surrounds survey switch switched switches switching symmetric symmetry system systematic systems table tables take taken takes taking talk talked talking tapes target task tax teacher teachers teaching teachings team technical technique techniques technology teeth telephone temp temperature temporary ten tend tends term terminal terminals terminated terminating termination terms test tested testing tests texas text than that the their them themselves then theorem theoretical theory there thereby therefore thereof these they thick thickness thin thing things think thinking third thirty this those though thought three threshold through throughout thus time times timing tip tips title to today together toggled told tolerances tone too took top total touch toward towards track trade traditional traffic train training transaction transfer transformation transformations transistor transistors transition translated translation transmission transmit transmitted travel traverse treated treatment tree trees trial triangle tried triggered trip trivial trouble truck true truly try trying tube turn turned turning turns twenty twice two type types typical typically ultimate unaltered unchanged undefined under underlying understand understanding understood unequal unfortunately unidirectionality unidirectionally uniform union unique unit united units unity universe university unless unrelated unstable until unusual up update upon upper us usage use used useful useless user users uses using usual usually utility utilization utilized utilizing valid validity value values van variable variables variance variation varied variety various vary vast vector vectors verification verified version versions vertical very via view viewed vis visible vision visit vital vocational voice voids voltage voltages volume wait waiting wall walls want wanted wants war was washington water wavelength way ways we week weeks weight weighting weights well went were western what whatever when whenever where whereby wherein wherever whether which while white who whole whom whose why wide width will william willing wind wise wish with within without women word words work worked workers working works world worst worth would write writer writers writing written wrong wrote year years yes yet yield yields york you young your zero zone zones aiting wall walls want wanted wants war was washington water wavelength way ways we week weeks weight weighting weights well went were #define UMAX 50 #define CLDSIG 18 char mesg[3000]; int msize; struct UTMP { char name[8]; char ln[2]; int time[2]; int pid; } utmp[UMAX]; struct { char lobyte; char hibyte; }; char who[9] "???"; char line[] "/dev/lnxx"; main(argc, argv) char *argv[]; { int i; register struct UTMP *p; register f; f = open("/etc/utmp", 0); if(f < 0) { printf("utmp?\n"); exit(1); } read(f, utmp, sizeof(utmp)); close(f); i = lnxx(2); for(p = utmp; p < &utmp[UMAX]; p++) { if (p->ln[0] != i.lobyte || p->ln[1] != i.hibyte) continue; for (f=0; f<8; f++) if ((who[f] = p->name[f]) == ' ') break; else who[f] =& ~0200; who[f] = 0; break; } line[7] = i.lobyte; line[8] = i.hibyte; chmod(line, 0622); f = 0; if(argc >= 2) { f = open(argv[1], 0); if(f < 0) { printf("%s?\n", argv[1]); exit(1); } } while((i = read(f, &mesg[msize], sizeof mesg - msize)) > 0) msize =+ i; close(f); signal(CLDSIG, 1); for(p = &utmp[0]; p < &utmp[UMAX]; p++) { if (!(p->name[0] & 0200)) continue; p->name[0] =& 0177; sleep(1); sendmes(p); } } sendmes(p) struct UTMP *p; { register i; register char *s; register int try; try = 0; while ((i = fork()) == -1) { if (++try == 4) { printf("Can't fork!\n"); exit(2); } sleep(5); } if(i) return; s = "/dev/lnxx"; s[7] = p->ln[0]; s[8] = p->ln[1]; i = open(s, 1); if(i < 0) { printf("Cannot send to %8.8s\n", p->name); exit(1); } close(1); dup(i); printf("\07\07\07Broadcast Message from %s (%s) ...\n\n", who, &line[5]); write(1, mesg, msize); exit(0); } ndmes(p); } } sendmes(p) struct UTMP *p; { register i; register char *s; register int try; try = 0; while ((i = fork()) == -1) { if (++try == 4) { printf("Can't fork!\n"); exit(2); } sleep(5); } if(i) return; s = "/dev/lnxx"; s[7] = p->ln[0]; s[8] = p->ln[1]; i = open(s, 1); if(i < 0) { printf("Cannot send to %8.8s\n", p->name); exit(1); } close(1); dup(i); printf("\07\07\07Broadcast Message from %s (%s) ...\n\n", who, &/* wc line and word count */ int buf[259]; long wordct; long twordct; long linect; long tlinect; long charct; long tcharct; main(argc,argv) char **argv; { int i, token, wd; register char *p1, *p2; register int c; wd = 0; if(argc > 1 && *argv[1] == '-') { wd = 1; argc--; argv++; } i = 1; do { if(argc<=1) buf[0] = 0; else if(fopen(argv[i],buf)<0) { diag(argv[i]); diag(": cannot open\n"); continue; } p1 = 0; p2 = 0; linect = 0; wordct = 0; charct = 0; token = 0; for(;;) { if(p1 >= p2) { p1 = &buf[1]; c = read(buf[0], p1, 512); if(c <= 0) break; charct =+ c; p2 = p1+c; } c = 0; c =| *p1++; if(' ' 2) { if(!wd) printf("%7ld ",tlinect); printf("%7ld ",twordct); if(!wd) printf("%7ld total\n", tcharct); else printf("\n"); } } diag(s) char *s; { while(*s) write(2,s++,1); } =' '&&c!='\t') continue; token = 0; } } if(!wd) printf("%7ld ", linect); printf("%7ld", wordct); if(!wd) printf(" %7ld %s\n", charct, argc<=1?"":argv[i]); else printf("\n"); close(buf[0]); tlinect =+ /* * WHO COMMAND--gives a listing of processes spun off by init. * * Processes are divided into four categories: * 'u'-Users who are logged in on the system * 'l'-Lines on which "getty" has been spun off, yet no one has logged * in yet. Note that WHO does not make a distinction between * the programs "login" and "getty" in giving its report. * 'p'-Processes other than getty which have been spun off by init. * (e.g., line printer daemon, alerter, update) * 'd'-Dead lines. This category includes a listing of all lines * on which a process was at one time active but was * subsequently killed by init without being respun. * (e.g., rc) * 'r'-Run level is printed along with the time it was last changed * 'b'-Instances of a hardware boot invoking /etc/init * * 'am i'-identifies the line id of the requestor * Format for use of this command: * who [-ulpdarb] [who file] * who am i * * Where u, l, p, and d are as described above and a is * identical to all four. The default who file is /etc/utmp. * */ int fout; int buf[256]; char uflag, lflag, pflag, dflag, rflag, wflag,bflag; struct wline { char name[8]; int ln; int time[2]; int pid; } ; main(argc, argv) int argc; char *argv[]; { int fi; register struct wline *p; register i,n; char *s; s = "/etc/utmp"; switch(argc) { case 1: uflag=1; goto go; case 2: if (*argv[1] != '-') { uflag=1; s=argv[1]; goto go; } setflags: while (*(++argv[1])) switch(*argv[1]) { case 'u': uflag = 1; break; case 'l': lflag = 1; break; case 'p': pflag = 1; break; case 'd': dflag = 1; break; case 'r': rflag = 1; break; case 'b': bflag = 1; break; case 'a': dflag=pflag=lflag=uflag=rflag=bflag=1; break; default: write(1,"bad flag\n", 9); exit(); } break; case 3: if(argv[1][0] == 'a' && argv[1][1] == 'm'){ wflag = 1; break; } s=argv[2]; goto setflags; default: write(1, "arg count\n", 10); exit(); } go: fi = open(s,0); if (fi<0) { write(1, "cannot open who file\n", 21); exit(); } fout = dup(1); close(1); loop: n=read(fi,buf,512); if (n <= 0) { flush(); exit(); } for (p = &buf; (n =- 16) >= 0; p++) { if (p->ln == 0) continue; if (p->name[0] < 0) { p->name[0] =& ~0200; if(wflag && lnxx(0) == p->ln){ putline(p); flush(); exit(); } if (uflag) putline(p); continue; } if (p->name[0] > 0) { if(rflag && p->ln == 'RL'){ printf("RUN STATE = "); if(p->pid < 0) printf("SINGLE USER"); else printf("%d",p->pid); printf("%-13.13s\n",ctime(p->time)+3); continue; } if (bflag && p->ln == '!B'){ putline(p); continue; } if(p->ln == 'RL' || p->ln == '!B') continue; if (pflag) putline(p); continue; } if (p->pid) { if (lflag) { for (i=0; i<7; i++) p->name[i] = "LOGIN "[i]; putline(p); } continue; } if (dflag) { for (i=0; i<7; i++) p->name[i] = '*'; putline(p); continue; } } goto loop; } putline(p) struct wline *p; { printf("%-8.8s ln%-2.2s%-13.13s%6l\n", p->name, &(p->ln), ctime(p->time)+3, p->pid); } flag && p->ln == '!B'){ putline(p); continue; } if(p->ln == 'RL' || p->ln == '!B') continue; if (pflag) putline(p); continue; } if (p->pid) { if (lflag) { for (i=0; i<7; i++) p->name[i] = "LOGIN "[i]; putline(p); } continue; } if (dflag) { for (i=0; i<7; i++) p->name[i] = '*'; putline(p); continue; } } goto loop; } putline# /* tail command * * tail where [file] * where is +_n[type] * - means n lines before end * + means nth line from beginning * type 'b' means tail n blocks, not lines * type 'c' means tail n characters */ #define LBIN 4097 #define ESPIPE 29 struct { long longint; }; char bin[LBIN]; int *buf bin; int errno; main(argc,argv) char **argv; { long n,di; int fromend; register i,j,k; char *p; int partial,piped,bylines; char *arg; seek(0,0,1); piped = errno==ESPIPE; arg = argv[1]; if(argc<=1 || *arg!='-'&&*arg!='+') { arg = "-10l"; argc++; argv--; } fromend = *arg=='-'; arg++; if(!digit(*arg)) goto errcom; n = 0; while(digit(*arg)) n = n*10 + *arg++ - '0'; if(!fromend&&n>0) n--; if(argc>2) { close(0); if(open(argv[2],0)!=0) { write(2,"tail: can't open input\n",23); exit(1); } } bylines = 0; switch(*arg) { case 'b': n =<< 9; break; case 'c': break; case '\0': case 'l': bylines = 1; break; default: goto errcom; } if(fromend) goto keep; /*seek from beginning */ if(bylines) { j = 0; while(n-->0) { do { if(j--<=0) { p = bin; j = read(0,p,512); if(j--<=0) exit(0); } } while(*p++ != '\n'); } write(1,p,j); } else if(n>0) { if(!piped) fstat(0,buf); if(piped||(buf[2]&060000)==020000) while(n>0) { i = n>512?512:n; i = read(0,bin,i); if(i<=0) exit(0); n =- i; } else lseek(0,n,0); } while((i=read(0,bin,512))>0) write(1,bin,i); exit(0); /*seek from end*/ keep: if(n<=0) exit(0); if(!piped) { fstat(0,bin); bin[8] = 0; di = !bylines&&ndi) lseek(0,-di,2); } partial = 1; for(;;) { i = 0; do { j = read(0,&bin[i],LBIN-i); if(j<=0) goto brka; i =+ j; } while(i=LBIN ? i+1: i-n+LBIN; k--; } else { k = i; j = 0; do { do { if(--k<0) { if(partial) goto brkb; k = LBIN -1; } } while(bin[k]!='\n'&&k!=i); } while(j++=LBIN) k = 0; } while(bin[k]!='\n'&&k!=i); } if(k='0'&&c<='9'); } n>=LBIN ? i+1: i-n+LBIN; k--; } else { k = i; j = 0; do { do { if(--k<0) { if(partial) goto brkb; k = LBIN -1; } } whiint open[9] { 1 }; int n 1; int t 0; char in[512]; char out[512]; main(argc,argv) char **argv; { int register r,w,p; struct { int x1[2], type, x2[15]; } buf; int ignore(); if (argv[1][0] == '-') /* if invoked as '-' ignore interrupts */ signal(1, &ignore); fstat(1,&buf); t = (buf.type&060000)==020000; while(argc-->1) { open[n++] = creat(argv[1],0666); if(stat(argv[1],&buf)>=0) if((buf.type&060000)==020000) t++; argv++; } r = w = 0; for(;;) { for(p=0;p<512;) { if(r>=w) { if(t>0&&p>0) break; w = read(0,in,512); r = 0; if(w<=0) { stash(p); return; } } out[p++] = in[r++]; } stash(p); } } stash(p) { int k; int i; int d; d = t ? 10 : p; for(i=0; i1) { open[n++] = creat(argv[1],0666); if(stat(argv[1],&buf)>=0) if((buf.type&060000)==020000) t++; argv++; } r = w = 0; for(;;) { for(p=0;p<512;) { if(r>=w) { # #define ALARM 14 /* * write to another user */ struct utmp { char name[8]; int ttyno; int fill[3]; }; struct { char pad[4]; int flag; }; char me[10] "???"; char tty[] "/dev/ln\0\0"; char *him; int ttyno; int mytty; int histty; int logcnt; char buf[512]; int tf; int eof(); int timout(); main(argc, argv) char *argv[]; { register i,k; register struct utmp *p; int c1, c2, uf; struct{ char lobyte; char hibyte; }; if(argc < 2) { prs(1, "usage: write user [lineno]\n"); exit(1); } him = argv[1]; if(argc > 2){ ttyno.lobyte = argv[2][0]; ttyno.hibyte = argv[2][1]; } if((uf=open("/etc/utmp",0)) < 0){ prs(1, "cannot open /etc/utmp\n"); exit(); } mytty = lnxx(1); if(mytty.lobyte == 'x' && mytty.hibyte == 'x'){ prs(1,"nonexistent line\n"); exit(); } while((k=read(uf,buf,512)) > 0){ for(p=buf;(k =- 16) >= 0;p++){ if(p->name[0] >= 0)continue; p->name[0] =& ~0200; if(mytty == p->ttyno) for(i=0; i<8; i++) { c1 = p->name[i]; if(c1 == ' ')c1 = 0; me[i] = c1;  if(c1 == 0) break; } if(him[0] != '-' || him[1] != 0) for(i=0; i<8; i++) { c1 = him[i]; c2 = p->name[i]; if(c1 == 0) if(c2 == 0 || c2 == ' ') break; if(c1 != c2) goto loop; } logcnt++; c1 = p->ttyno; if(ttyno != 0 && ttyno != c1) continue; if(histty == 0) histty = c1; loop: ; } } close(uf); if(ttyno == 0 && logcnt > 1 && *him != '-') printf("%s multiply logged in\nwriting to ln%-2.2s\n", him,&histty); if(histty == 0) { prs(1, him); if(logcnt) prs(1, " not on that line\n"); else prs(1, " not logged in\n"); exit(1); } tty[7] = histty.lobyte; tty[8] = histty.hibyte; signal(ALARM, timout); alarm(5); tf = open(tty, 1); alarm(0); if((tf<0) || (fstat(tf,buf)<0) || ((buf->flag & 2) == 0 && getuid())){ prs(1,"Permission denied\n"); exit(1); } sigs(eof); prs(tf, "\nMessage from "); prs(tf, me); write(tf," (ln",4); write(tf,&mytty,2); write(tf,")...\n",5); for(;;) { i = read(0, buf, 512); if(i <= 0) eof(); if(buf[0] == '!') { buf[i] = 0; ex(); continue; } write(tf, buf, i); } } timout() { prs(1, "Timeout opening his line\n"); exit(1); } eof() { prs(tf, "EOT\n"); exit(0); } prs(f, s) char *s; { register n; for(n=0; s[n]; n++); write(f, s, n); } ex() { register i; sigs(1); i = fork(); if(i < 0) { prs(1, "Try again\n"); sigs(eof); } if(i == 0) { sigs(0); execl("/bin/sh", "sh", "-c", buf+1, 0); exit(0); } while(wait(buf) != i); prs(1, "!\n"); } sigs(sig) { register i; for(i=1; i<4; i++) signal(i,sig); } ; ex(); continue; } write(tf, buf, i); } } timout() { prs(1, "Timeout opening his line\n"); exit(1); } eof() { prs(tf, "EOT\n"); exit(0); } prs(f, s) char *s; { register n; for(n=0; s[n]; n++); write(f, s, n); } ex() { register i; sigs(1); i = fork(); if(i < 0) { prs(1, "Try again\n"); sigs(eof); } if(i == 0) { sigs(0); execl("/bin/sh", "sh", "-c", buf+1, 0); exit(0); } while(wait(buf) != i); prs(1, "!\n"); } sigs(sig) { register i; for(i=1; i<4; i++access alloc aretu backup badblock bawrite bcopy bdwrite bflush binit bmap bread breada brelse bwrite canon catintr chdir chmod chown cinit clearseg clock close closef closei clrbuf copyin copyout copyseg core cpass creat ctclose ctopen ctwrite daclose daopen daread dawrite dcclose dcopen dcread dcrint dcsgtty dcwrite dcxint devstart dhclose dhopen dhparam dhread dhrint dhsgtty dhstart dhwrite dhxint display dmint dmopen dnclose dnint dnopen dnwrite dpadd dpclose dpcmp dpopen dpread dprint dpstart dptimeout dpturnaround dpwait dpwrite dpxint draaint drabint dup estabur exec exit expand falloc flushtty fork free fstat fubyte fuword getblk getc geterror getf getfs getgid getmdev getpid getswit getuid glclose glintr glopen glread glsetchan glsetpoll glsgtty glwait glwrite gtime gtty hcommand hpintr hpopen hpphys hpread hpstart hpstrategy hpwrite hsintr hsread hsstart hsstrategy hswrite htclose htintr htopen htphys htread htstart htstrategy htwrite ialloc idle ifree iget iinit incore incupc iodone iomove iowait iput issig itrunc iupdat kill klclose klopen klread klrint klsgtty klwrite klxint ldiv link lpcanon lpclose lpint lpopen lpoutput lpstart lpwrite lrem lshift main maknode malloc max mfree min mknod mmread mmwrite namei newproc nice nodev nosys notavail nseg nulldev nullsys open open1 openi owner panic passc pcclose pcleader pcopen pcoutput pcpint pcread pcrint pcstart pcwrite physio pipe plock prdev prele printf printn profil psig psignal putc putchar rdwr read readi readp retu rexit rfintr rfread rfstart rfstrategy rfwrite rhstart rkaddr rkintr rkread rkstart rkstrategy rkwrite rpintr rpphys rpread rpstart rpstrategy rpwrite savfp savu sbreak schar sched seek setgid setrun setuid sgtty signal sleep smdate smount snstat spl0 spl1 spl4 spl5 spl6 spl7 ssig sslep stat stat1 stime stiuchan stty subyte sumount sureg suser suword swap swtch sync tcclose tcintr tcommand tcstart tcstrategy timeout times tiubusy tiuchan tiucheck tiucherr tiuclose tiuerr tiuintr tiuopen tiuptr tiuread tiustart tiustop tiustrategy tiuwrite tmclose tmintr tmopen tmphys tmread tmstart tmstrategy tmwrite toyfl trap trap1 ttread ttrstrt ttstart ttwrite ttyinput ttyoutput tyaintr tybintr tyopen tyread tysgtty tywrite uchar ufalloc unlink update vrintr vrstart vrstrategy vschar vsclose vsopen vsread vsrintr vswrite vsxintr vtclose vtintr vtopen vtwrite wait wakeup wdir wflushtty write writei writep wstiuchan xalloc xccdec xfree xswap busy tiuchan tiucheck tiucherr tiuclose tiuerr tiuintr tiuopen tiuptr tiuread tiustart tiustop tiustrategy tiuwriav_back av_forw b_addr b_back b_blkno b_dev b_error b_flags b_forw b_resid b_wcount bdevsw bfreelist buf buffers c_arg c_cc c_cf c_cl c_func c_next c_time call callo callout canonb cat catbuf catcsr catlock cblock cc ccc cdevsw cf cfree cfreelist cl clist coremap count csr csw cylin cyloff d_actf d_active d_actl d_close d_errcnt d_major d_minor d_open d_read d_sgtty d_strategy d_tab d_write dc11 dcrbuf dcrcsr dcregs dcrstab dctbuf dctcsr dctstab devtab dh11 dhbar dhbcr dhbreak dhcar dhcsr dhlpr dhnxch dhregs dhsar dhsilo dmcsr dmlstat dmregs dn dn11 dn_reg dn_stat dp11 dp_buf dp_bufp dp_nxmit dp_proc dp_state dp_timer dprbuf dprcsr dpsyn0 dpsyn1 dptbuf dptcsr draa dracsr drarbuf draxbuf drba drdb drst drwc execnt f_count f_flag f_inode f_offset file filsys flag g_state gl_iq glance glcsr glrbuf glxbuf h_blkno h_nxrec h_openf hbyte hibyte hp_openf hp_sizes hpas hpba hpbuf hpca hpcc hpcs1 hpcs2 hpda hpdb hpds hpdt hper1 hper2 hper3 hpla hpmr hpof hppat hppos hpsn hptab hpwc hsba hscs1 hscs2 hsda hsds hser hstab hswc htas htba htck htcs1 htcs2 htdb htds htdt hter htfc htmr htsn httab httc htwc i_addr i_count i_dev i_flag i_gid i_lastr i_mode i_nlink i_number i_size0 i_size1 i_uid icode info inode integ iq ka6 kisa6 kl11 klrbuf klrcsr klregs kltbuf kltcsr lbolt lbyte lks lksp lobyte lp11 lpbuf lpsr m_addr m_bufp m_dev m_inodp m_size map maptab maxfp maxip maxmem mcc mlc mount mpid nblkdev nblocks nchrdev ndh11 nswap oq p_addr p_flag p_pid p_ppid p_pri p_sig p_size p_stat p_textp p_time p_ttyp p_uid p_wchan pad panicstr partab pc11 pcin pcout pcpbuf pcpcsr pcrbuf pcrcsr pcstate proc r rablock raflag rbr regloc rfba rfcs rfda rfdae rftab rfwc rhsbuf rhtbuf rkba rkcs rkda rkds rker rktab rkwc rootdev rootdir rp_sizes rpba rpca rpcs rpda rpds rper rptab rpwc rrfbuf rrkbuf rrpbuf rsr rtmbuf runin runout runrun s_flock s_fmod s_free s_fsize s_ilock s_inode s_isize s_nfree s_ninode s_ronly s_time swapdev swapmap swbuf swplo sysent t_actf t_actl t_addr t_blkno t_buffer t_canq t_chan t_char t_col t_delct t_fill t_flags t_intrup t_isig t_nxrec t_openf t_osig t_outq t_quit t_rawq t_speeds t_state t_troub t_wflg tcba tccm tccsr tcdt tctab tcwc text time tiu tiu_cchan tiu_dchan tiuch tmba tmbc tmcs tmdb tmer tmrd tmtab tout toy toycsr toyin toyindir toyou toyresp trksec ttrbuf ttrcsr tttbuf tttcsr tty u u_ar0 u_arg u_base u_cdir u_count u_cstime u_cutime u_dbuf u_dent u_dirp u_dsize u_dsleep u_error u_fsav u_gid u_ino u_name u_nice u_offset u_ofile u_pdir u_procp u_prof u_qsav u_rgid u_rsav u_ruid u_segflg u_signal u_ssav u_ssize u_stime u_tsize u_uid u_uisa u_uisd u_utime updlock user vr_sizes vraddress vrcar vrcommand vrcount vrcsr vrseek vrtab vs vsmap vsrbuf vsrcsr vsxbuf vsxcsr vtflag vtreg x_caddr x_ccount x_count x_daddr x_iptr x_size xbr xsr r toyou toyresp trksec ttrbuf ttrcsr tttbuf tttcsr tty u u_ar0 u_arg u_base u_cdir u_count u_cstime u_cutime u_dbuf u_dent u_dirp u_dsize u_dsleep u_error u_fsav u_gid u_ino u_name u_nice u_offset u_ofile u_pdir u_procp u_prof u_qsav u_rgid u_rsav u_ruid u_segflg u_signal u_ssav u_ssize ucp /dev/null tmprhole if $1x != x goto test : bads echo file of source files not given goto out : test if ! -r $1 goto bads if { cmp $1 /dev/null >tmprhole } goto bads if $2x = x goto default if -r $2 goto have2 : badf echo file of functions is bad goto out : have2 cp $2 tmpfuns goto cont1 : default if ! -r functions goto badf cp functions tmpfuns : cont1 if { cmp tmpfuns /dev/null >tmprhole } goto badf : at this point have a good source file and function file grep "mch\.s" $1 >tmpmch : now build a shell to cref the c source ed - $1 v/mch\.s/s/^/cref -cot tmpfuns tmpcref / v/mch\.s/s/$/ \/dev\/null;tr "[\\177-\\377]" "[\\011*]" >tmpallcref/ g/mch\.s/s/^.*$/cmp & &/ w tmpsh q cp /dev/null tmpcref cp /dev/null tmpallcref sh tmpsh rm tmpsh cp /dev/null tmpcref if { cmp tmpmch /dev/null >tmprhole } goto nomch ed - tmpmch g/^/s/^/cref -aot tmpfuns tmpcref / g/$/s/$/ \/dev\/null/ w tmpmch e tmpfuns g/^/s/^/_/ w tmpfuns q sh tmpmch if { cmp tmpcref /dev/null >tmprhole } goto nomch ed - tmpcref g/^_/s/// g/[^,]_/s/_// w tmpcref q tr "[\177-\377]" "[\011*]" >tmpallcref : nomch rm tmpmch tmpfuns sort rawfcref rm tmpcref tmpallcref : out rm tmprhole /dev/null tmpcref cp /dev/null tmpallcref sh tmpsh rm tmpsh cp /dev/null tmpcref if { cmp tmpmch /dev/null >tmprhole } goto nomch ed - tmpmch g/^/s/^/cref -aot tmpfuns tmpcref / g/$/s/$/ \/dev\/null/ w tmpmch e tmpfuns g/^/s/^/_/ w tmpfuns q sh tmpmch if { cmp tmpcref /dev/null >tmprhole } goto nomch ed - tmpcref g/^_/s/// g/cp /dev/null temprhole if $1x != x goto test : bad echo file of source files not given goto out : test if ! -r $1 -o ! -w $1 goto bad if { cmp $1 /dev/null >temprhole } goto bad ed - $1 v/mch\.s/s/^/grep "^[abcdefghijklmnopqrstuvwxyz0123456789]*(" / g/mch\.s/s/^/grep "^_[abcdefghijklmnopqrstuvwxyz0123456789]*:" / g/$/s/$/ >>tempfuns/ w tempfsh q cp /dev/null tempfuns sh tempfsh if { cmp tempfuns /dev/null >temprhole } goto nof ed - tempfuns g/(.*$/s/// g/:/s/// g/_/s/// g/cannot open/d g/ka6/d w tempfuns q sort tempsfuns mv tempsfuns tempfuns : nof rm tempfsh if $2x = x goto no2 mv tempfuns $2 goto out : no2 mv tempfuns functions : out rm temprhole >temprhole } goto bad ed - $1 v/mch\.s/s/^/grep "^[abcdefghijklmnopqrstuvwxyz0123456789]*(" / g/mch\.s/s/^/grep "^_[abcdefghijklmnopqrstuvwxyz0123456789]*:" / g/$/s/$/ >>tempfuns/ w tempfsh q cp /dev/null tempfuns sh tempfsh if { cmp tempfuns /dev/null >temprhole } goto nof ed - tempfuns g/(.*$/s/// g/:/s/// g/_/s/// g/cannot open/d g/ka6/d w tempfuns q cp /dev/null tmmprhole if $1x != x goto test : bads echo file of source files not given goto out : test if ! -r $1 goto bads if { cmp $1 /dev/null >tmmprhole } goto bads if $2x = x goto default if -r $2 goto have2 : badf echo file of variables is bad goto out : have2 cp $2 tmmpfuns goto cont1 : default if ! -r variables goto badf cp variables tmmpfuns : cont1 if { cmp tmmpfuns /dev/null >tmmprhole } goto badf : at this point have a good source file and function file grep "mch\.s" $1 >tmmpmch : now build a shell to cref the c source ed - $1 v/mch\.s/s/^/cref -cot tmmpfuns tmmpcref / v/mch\.s/s/$/ \/dev\/null; tr "[\\177-\\377]" "[\\011*]" >tmmpallcref/ g/mch\.s/s/^.*$/cmp & &/ w tmmpsh q cp /dev/null tmmpcref cp /dev/null tmmpallcref sh tmmpsh rm tmmpsh cp /dev/null tmmpcref if { cmp tmmpmch /dev/null >tmmprhole } goto nomch ed - tmmpmch g/^/s/^.*$/cref -aot tmmpfuns tmmpcref & \/dev\/null/ w tmmpmch e tmmpfuns g/^/s/^/_/ w tmmpfuns q sh tmmpmch if { cmp tmmpcref /dev/null >tmmprhole } goto nomch ed - tmmpcref g/^_/s/// g/mch\.s._/s/_// g/\.globl/d w tmmpcref q tr "[\177-\377]" "[\011*]" >tmmpallcref : nomch rm tmmpmch tmmpfuns sort rawvcref rm tmmpcref tmmpallcref : out rm tmmprhole ef cp /dev/null tmmpallcref sh tmmpsh rm tmmpsh cp /dev/null tmmpcref if { cmp tmmpmch /dev/null >tmmprhole } goto nomch ed - tmmpmch g/^/s/^.*$/cref -aot tmmpfuns tmmpcref & \/dev\/null/ w tmmpmch e tmmpfuns g/^/s/^/_/ w tmmpfuns q sh tmmpmch if { cmp tmmpcref /dev/null >tmmprhole } goto nomch ed#define LINELEN 136 #define NUMLONG 40 #define NAMELEN 12 struct info { char func[NAMELEN]; char file[NAMELEN]; char caller[NAMELEN]; } ; struct info last; char text[LINELEN]; struct buff { int fdes; int nleft; char *nextp; char area[512]; } buf; char longfs[NUMLONG][NAMELEN]; int numlfun; main(argc,argv) char *argv[]; { extern fout; if(argc-- < 3) { printf("arg count\n"); exit(12); } if(!fopen(&buf,*++argv)) { printf("cannot open: %s\n",*argv); exit(12); } for(numlfun = 0; numlfun < NUMLONG && getlong(); numlfun++) move(text,longfs[numlfun]); if(numlfun == NUMLONG) printf("warning: too many long functions\n"); close(buf.fdes); blankit(&last,3 * NAMELEN); blankit(text,LINELEN); fout = dup(1); while (--argc && *++argv) { if(!fopen(&buf,*argv)) { printf("cannot open: %s\n",*argv); flush(); continue; } while (getline()) ckline(); close(buf.fdes); } flush(); } getline() { register int c, dlm; register char *p; char *ptr; blankit(text,3 * NAMELEN); p = text; while ((c = get(&buf)) >= 0) { if(c == '\n') { *p = 0; return(1); } c =& 0377; switch(dlm) { case 0: case 1: case 2: if(c == '\t') { ptr = &text[dlm * NAMELEN]; if(p - ptr > 6) if(p = bsrch(longfs,ptr,numlfun,p - ptr)) move(p,ptr); p = &text[++dlm * NAMELEN]; } else *p++ = c; break; case 3: if(c == '\t' ) p = &text[dlm++ * NAMELEN]; break; default: *p++ = c; } } return(0); } ckline() { int nl, j; register int offset; nl = 0; for (j = 0; j < 3; j++) { offset = j * NAMELEN; if(compar(&last.func[offset],&text[offset],NAMELEN) || nl) { if(j == 0) { putchar('\n'); nl++; } move(&text[offset],&last.func[offset]); } else blankit(&text[offset],NAMELEN); } pukeln(); } pukeln() { register char *p; for(p = text; *p; p++) putchar(*p); putchar('\n'); } move(from,to) char *from,*to; { register char *f,*t; register i; f = from; t = to; for (i = 0; i < NAMELEN; i++) *t++ = *f++; } fopen(b,file) struct buff *b; char *file; { b->nleft = 0; if((b->fdes = open(file,0)) < 0) return(0); return(1); } get(p) struct buff *p; { if(p->nleft == 0) { if((p->nleft = read(p->fdes,p->area,512)) == 0) return(-1); p->nextp = p->area; } p->nleft--; return(*p->nextp++ & 0377); } blankit(ptr,len) char *ptr; { register l; register char *p; l = len; p = ptr; while(l--) *p++ = ' '; } bsrch(start,name,items,namelen) char *name, *start; { register int hi, lo, mid; char *p; int c; if (items < 1) return(0); hi = items - 1; lo = 0; mid = (hi + lo) / 2; while (hi - lo > 1) { if ((c = compar(start + mid * NAMELEN,name,namelen)) == 0) return(start + mid * NAMELEN); else if(c > 0) hi = mid; else lo = mid; mid = (hi + lo) / 2; } p = start + lo * NAMELEN; if (compar(p,name,namelen) == 0) return(p); p = start + hi * NAMELEN; return(compar(p,name,namelen) == 0 ? p : 0); } compar(f,s,len) char *f,*s; { register i, j, k; for(k = 0; k < len; k++) if((i = *f++) != (j = *s++)) return(i < j ? -1 : 1); return(0); } getlong() { register char *p; while(1) { blankit(text,NAMELEN); for(p = text; (*p = get(&buf)) != '\n'; p++) if (*p < 0) return(0); *p = ' '; if(p - text > 8) return(1); } } = mid; mid = (hi + lo) / 2; } p = start + lo * NAMELEN; if (compar(p,name,namelen) == 0) return(p); p = start + hi * NAMELEN; return(compar(p,name,namelen) == 0 ? p : 0); } compar(f,s,len) char *f,*s; { register i, j, k; for(k = 0; k < len; k++) if((i = *f++) != (j = *s++)) return(i < j ? -1 : # # include "mcons.c" # include "ccmn.c" # define SKIP 0 # define COLLECT 1 # define SKIP2 2 int cross 1; int order 1; char mone -1; coll() { cs = COLLECT; temp[t1].beg = &line[l]; return; } save() { extern wspace(); line[l] = '\0'; temp[t1].ct = &line[l] - temp[t1].beg; temp[t1].term = c; if((c == ' ' || c == '\t') && cflag) { gch[++fl] = mone; flag[fl] = &wspace; } else { sav1(); } return; } sav1() { extern only; struct tempent *ptr; int a,tt,val; ptr = &temp[t1]; val = search(ptr->beg,ptr->ct,&itab,0); if(cflag && c == '(' && level == 0 && hlevel == 0) csym(); cs = SKIP; if(xsw) { switch(val) { case 0: if((!level&&!hlevel)||(c == '(')||xtrn || ssw) { search(ptr->beg,ptr->ct,&xtab,1); goto yes; } else { if(search(ptr->beg,ptr->ct,&xtab,0)) goto yes; } goto no; case 1: break; case 2: xtrn = 1; goto no; case 3: if(hlevel) type = 1; if(!level&&!hlevel) ssw = 1; goto no; case 4: if(hlevel) type = 1; goto no; case 5: goto no; } } if(hlevel && (val == 4 || val == 3)) type = 1; if(!val == !only) goto yes; no: *(ptr->beg + ptr->ct) = ptr->term; return(0); yes: tt = t1; while(tt) if(comp(ptr->beg,temp[--tt].beg)) goto no; t1++; return(1); } out() { auto i,ct; if(cs == COLLECT) save(); ct = t1; while(ct--) temp[ct].beg[temp[ct].ct] = temp[ct].term; while(t1--) { /*printf("t1 = %d beg = %d ct = %d\n",t1,temp[t1].beg,temp[t1].ct); /* DEBUG */ switch(order) { case 1:  if(utmp) i = 0; else i = dfile(temp[t1].beg); if((ct = temp[t1].ct) >= 8) { ct = 8; *curf = -1; } else { *curf = '\t'; } put(i,temp[t1].beg,ct); if(!single) put(i, curf, curfl); else put(i, curf, 1); if(cross) put(i,curs,cursl); conf(lno,4,lbuf); put(i,lbuf,5); break; case 2: i = dfile(curf+1); put(i,curf+1,curfl-1); if(cross) put(i,curs,cursl); else { conf(lno,4,lbuf); put(i,lbuf,5); } if((ct = temp[t1].ct) >= 8) { put(i,temp[t1].beg,8); put(i,&mone,1); } else { put(i,temp[t1].beg,ct); put(i,"\t",1); } if(cross) { conf(lno,4,lbuf); put(i,lbuf,5); } break; case 3: i = dfile(curs); put(i,curs,cursl); if((ct = temp[t1].ct) >= 8) { put(i,temp[t1].beg,8); *curf = -1; } else { put(i,temp[t1].beg,ct); *curf = '\t'; } put(i,curf,curfl); conf(lno,4,lbuf); put(i,lbuf,5); } if(!nocont) put(i,line,l + 1); } t1 = 0; l = -1; lno++; cs = SKIP; return; } asym() { int i; char *p; if(cs == COLLECT) { if(cross) { p = temp[t1].beg; cursl = &line[l] - p; cursl = cursl>8?8:cursl; i = -1; while(++i < cursl) curs[i] = *p++; if(cursl < 8) curs[cursl++] = '\t'; else curs[cursl++] = -1; } save(); } cs = SKIP; } asw() { switch(gch[fl]) { case 0: if(cs == COLLECT) save(); cs = SKIP; flag[++fl] = &asw; gch[fl] = c; return(1); case '\'': if(c == '\\') { gch[fl] = c; return(1); } break; case '"': gch[fl] = '\''; if(c == '\\') { flag[++fl] = &asw; gch[fl] = c; return(1); } return(1); case '<': if(c == '\n') out(); if(c == '\\') { flag[++fl] = &asw; gch[fl] = c; return(1); } if(c != '>') return(1); break; case '/': if(c != '\n') return(1); case '\\': if(c == '\n') out(); } fl--; return(1); } csw() { if(cs == COLLECT) save(); switch(gch[fl]) {  case 0: if(c == '*') if(line[l - 1] != '/') return(1); gch[++fl] = c; flag[fl] = &csw; return(1); case '*': if(c == '\n') out(); if(c == '/' && line[l - 1] == '*') break; return(1); case '\'': case '"': if(c == gch[fl]) break; if(c == '\\') { gch[++fl] = c; flag[fl] = &csw; } return(1); case '\\': break; } fl--; return(1); } incl() { /* printf("incl: l = %d hl = %d dl = %d\n",level,hlevel,dlevel);/*DEBUG*/ if(cs == COLLECT) save(); if(hlevel) { hlevel = 0; level++; } else { dlevel++; } cs = SKIP; } decl() { /* printf("decl: l = %d hl = %d dl = %d\n",level,hlevel,dlevel);/*DEBUG*/ if(cs == COLLECT) save(); cs = SKIP; if(dlevel) { dlevel--; return; } if(--level > 0) return; curs[0] = '_'; curs[1] = '\t'; cursl = 2; level = 0; return; } csym() { int i; char *p; /* printf("csym: l = %d hl = %d dl = %d\n",level,hlevel,dlevel);/*DEBUG*/ /* printf("%s\n", temp[t1].beg); /*DEBUG */ p = temp[t1].beg; if(cs == COLLECT && level == 0) { if(cross) { cursl = temp[t1].ct; cursl = cursl>8?8:cursl; i = -1; while(++i < cursl) curs[i] = *p++; if(cursl < 8) curs[cursl++] = '\t'; else curs[cursl++] = -1; } hlevel = 1; } cs = SKIP; } dfile(a) char *a; { if(*a < 'c') return(0); if(*a < 'h') return(1); if(*a < 'r') return(2); return(3); } sk2() { cs = SKIP2; } sk() { cs = SKIP; } tabs() { if(l == 0) l = -1; } search(symbol,length,params,install) char *symbol; int length; struct htab *params; int install; { char *sp,*p; static int curb,*hptr,hsiz,nsym,ssiz; static char *symt; auto h,i,j,k; if(hptr != params->hptr) { hptr = params->hptr; hsiz = params->hsiz; symt = params->symt; ssiz = params->ssiz; curb = params->curb; nsym = params->nsym; } symbol[length] = '\0'; sp = symbol; i = length; h = 1; while(i--) h =* *sp++; if(h == 0100000) { h = 1; } else { h = h<0?(-h)%hsiz:h%hsiz; } if(h == 0) h++; /* printf("%s %d\n",symbol,h); /*DEBUG*/ while((p = &symt[hptr[h]]) > symt) { j = length + 2; sp = symbol; while(--j) { if(*p++ != *sp++) goto no; } return(*p); no: h = (h + h)%hsiz; } if(install) { if(++nsym >= hsiz) { printf("Too many symbols.\n"); dexit(); } hptr[h] = curb; length++; if((curb + length) >= ssiz) { printf("Too many characters in symbols.\n"); dexit(); } while(length--) symt[curb++] = *symbol++; symt[curb++] = install; params->curb = curb; params->nsym = nsym; } return(0); } conf(n,width,buf) char *buf; { auto i,a; i = width; while(i--) buf[i] = ' '; buf[(a = n/10)?conf(a,--width,buf):--width] = n%10 + '0'; return(++width); } comp(a,b) char *a; char *b; { a--; b--; while(*++a == *++b) if(*a == '\0') return(1); return(0); } semi() { if(cs == COLLECT) save(); if(only) return; xtrn = 0; if(!level) { ssw = 0; if(!type) { hlevel = 0; curs[0] = '_'; curs[1] = '\t'; cursl = 2; } type = 0; } cs = SKIP; } wspace() { if(c == ' ' || c == '\t') return(1); sav1(); fl--; return(0); } = width; while(i--) buf[i] = ' '; buf[(a = n/10)?conf(a,--width,buf):--width] = n%10 + '0'; return(++width); } comp(a,b) char *a; char *b; { a--; b--; while(*++a == *++b) if(*a == '\0') return(1); return(0); } semi() { if(cs == COLLECT) save(); if(only) return; xtrn = 0; if(!level) { ssw = 0; if(!type) { hlevel = 0; curs[0] = '_'; curs[1] = '\t'; cursl = 2; } type = 0; } cs = SKIP; } wspace() { if(c == ' ' || . .. r0 r1 r2 r3 r4 r5 sp pc csw mov movb cmp cmpb bit bitb bic bicb bis bisb add sub br bne beq bge blt bgt ble bpl bmi bhi blos bvc bvs bhis bec bcc blo bcs bes jbr jne jeq jge jlt jgt jle jpl jmi jhi jlos jvc jvs jhis jec jcc jlo jcs jes clr clrb com comb inc incb dec decb neg negb adc adcb sbc sbcb tst tstb ror rorb rol rolb asr asrb asl aslb jmp swab jsr rts sys clc clv clz cln sec sev sez sen cfcc setf setd seti setl clrf negf absf tstf movf movif movfi movof movfo addf subf mulf divf cmpf modf movie movei ldfps stfps fr0 fr1 fr2 fr3 fr4 fr5 als alsc mpy mul div ash ashc dvd xor sxt mark sob .byte .even .if .endif .globl .text .data .bss .comm bcc blo bcs bes jbr jne jeq jge jlt jgt jle jpl jmi jhi jlos jvc jvs jhis jec jcc jlo jcs jes clr clrb com comb inc incb dec decb neg negb adc adcb sbc sbcb tst tstb ror rorb rol rolb asr asrb asl aslb jmp swab jsr rts sys clc clv clz cln sec sev sez sen cfcc setf setd seti setl clrf negf absf tstf movf movif movfi movof movfo addf subf mulf divf cmpf modf movie skip collect save skip2 sk cont coll save out asym agobl csym cgobl incl decl sk2 sk collect/'/agobl; collect/"/agobl; collect/ 9)) {  printf("-d: 0 < d < 10\n"); exit(); } if(argv[1][2] == 'x') { ig = fct-1; } on: argv++; argc--; } else { fct = 3; } f = 0; while(++f < argc) { file = open(argv[f], 0); edf(file, fct); close(file); } flsh(0); exit(); } int lno 1; edf(file, fct) { auto i,j,l; extern lno,etext; char brk,*buf,bufsp[150],line[150]; char extern *sym[]; /* monitor(&main,&etext,&mbuf,1024); /*INSTR*/ for(i = 0; i < fct; i++) *sym[i] = 0200; fields: l = -1; buf = &bufsp; for(i = 0; i < fct; ++i) { buf--; swt: switch(*++buf = get(file)) { default: if(esw && *buf >= 'A' && *buf <= 'Z' && i == 0) *buf =| 040; goto swt; case -1: *buf = ' '; case '\t': if(i == ig) continue; brk = *buf; *buf = '\0'; buf = &bufsp; if(comp(buf, sym[i])) { if(esw && i == 0) { line[0] = line[1] = '\t'; l = 1; goto rest; } line[++l] = '\t'; continue; } else { copy(buf, sym[i]); l =+ copy(buf, &line[++l]); line[--l] = brk; if(l < 8 && esw && i == 0) line[++l] = '\t'; j = i; while(++j < fct) *sym[j] = 0200; continue; } case '\n': lno++; brk = *buf; *buf = '\0'; buf = &bufsp; if(comp(buf, sym[i])) { goto fields; } else { copy(buf, sym[i]); l =+ copy(buf, &line[++l]); line[--l] = '\n'; j = i; while(++j < fct) *sym[j] = 0; goto out; } case '\0': goto fexit; } } rest: while((line[++l] = get(file)) != '\n') if(line[l] == '\0') goto fexit; lno++; out: if(*line != '\t') { put(0,"\n",1); lno++; } put(0,line,++l); goto fields; fexit: /* monitor(0); /*INSTR*/ return(0); } copy(a, b) char *a,*b; { char *c; b--; c = --a; while(*++b = *++a); return(a - c); } comp(a, b) char *a, *b; { /* printf("comp: %s %s\n",a,b); /*DEBUG*/ a--; b--; while(*++a == *++b) { if(*a == '\0') return(1); } return(0); } char buf[512]; int nread 1; get(ifile) int ifile; { char static *ibuf; if(--nread){ return(*ibuf++); } if(nread = read(ifile,buf,512)){ if(nread < 0)goto err; ibuf = buf; return(*ibuf++); } nread = 1; return(0); err: nread = 1; printf("read error\n"); return(0); } int tp[1] 1; int optr[4]; char bsp[512]; char *obuf[1] bsp; int nflush; put(fil,string,n) char *string; { int i; char *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr[fil] + n - 512) >= 0) { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0) *++o = *++string; optr[fil] = 512; flsh(fil); n = i; } o = &obuf[fil][optr[fil]] - 1; optr[fil] =+ n; while(--n >= 0) { *++o = *++string; } return(0); } flsh(fil) { extern tp[]; if(optr[fil] <= 0) return(optr[fil]); nflush++; if(write(tp[fil],obuf[fil],optr[fil]) != optr[fil]) return(-1); optr[fil] = 0; return(0); } *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr[fil] + n - 512) >= 0) { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0auto 5 break 5 case 5 char 4 continue 5 default 5 do 5 double 4 else 5 extern 2 float 4 for 5 goto 5 if 5 include 5 int 4 long 4 register 5 return 5 static 5 struct 3 switch 5 while 5 { extern tp[]; if(optr[fil] <= 0) return(optr[fil]); nflush++; if(write(tp[fil],obuf[fil],optr[fil]) != optr[fil]) return(-1); optr[fil] = 0; return(0); } *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr[fil] + n - 512) >= 0) { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0skip collect save skip2 sk cont coll save out asym agobl csym cgobl incl decl sk2 sk tab semi collect/\;/semi; collect/_/cont; collect/{/incl; collect/}/decl; collect/'/cgobl; collect/\\/cgobl; collect/"/cgobl; collect/a/cont; collect/b/cont; collect/c/cont; collect/d/cont; collect/e/cont; collect/f/cont; collect/g/cont; collect/h/cont; collect/i/cont; collect/j/cont; collect/k/cont; collect/l/cont; collect/m/cont; collect/n/cont; collect/o/cont; collect/p/cont; collect/q/cont; collect/r/cont; collect/s/cont; collect/t/cont; collect/u/cont; collect/v/cont; collect/w/cont; collect/x/cont; collect/y/cont; collect/z/cont; collect/A/cont; collect/B/cont; collect/C/cont; collect/D/cont; collect/E/cont; collect/F/cont; collect/G/cont; collect/H/cont; collect/I/cont; collect/J/cont; collect/K/cont; collect/L/cont; collect/M/cont; collect/N/cont; collect/O/cont; collect/P/cont; collect/Q/cont; collect/R/cont; collect/S/cont; collect/T/cont; collect/U/cont; collect/V/cont; collect/W/cont; collect/X/cont; collect/Y/cont; collect/Z/cont; collect/1/cont; collect/2/cont; collect/3/cont; collect/4/cont; collect/5/cont; collect/6/cont; collect/7/cont; collect/8/cont; collect/9/cont; collect/0/cont; collect/ /out; skip/\;/semi; skip/_/coll; skip/ /tab; skip/{/incl; skip/}/decl; skip/*/cgobl; skip/'/cgobl; skip/"/cgobl; skip/\\/cgobl; skip/ /out; skip/1/sk2; skip/2/sk2; skip/3/sk2; skip/4/sk2; skip/5/sk2; skip/6/sk2; skip/7/sk2; skip/8/sk2; skip/9/sk2; skip/0/sk2; skip/a/coll; skip/b/coll; skip/c/coll; skip/d/coll; skip/e/coll; skip/f/coll; skip/g/coll; skip/h/coll; skip/i/coll; skip/j/coll; skip/k/coll; skip/l/coll; skip/m/coll; skip/n/coll; skip/o/coll; skip/p/coll; skip/q/coll; skip/r/coll; skip/s/coll; skip/t/coll; skip/u/coll; skip/v/coll; skip/w/coll; skip/x/coll; skip/y/coll; skip/z/coll; skip/A/coll; skip/B/coll; skip/C/coll; skip/D/coll; skip/E/coll; skip/F/coll; skip/G/coll; skip/H/coll; skip/I/coll; skip/J/coll; skip/K/coll; skip/L/coll; skip/M/coll; skip/N/coll; skip/O/coll; skip/P/coll; skip/Q/coll; skip/R/coll; skip/S/coll; skip/T/coll; skip/U/coll; skip/V/coll; skip/W/coll; skip/X/coll; skip/Y/coll; skip/Z/coll; skip2/{/incl; skip2/}/decl; skip2/a/cont; skip2/b/cont; skip2/c/cont; skip2/d/cont; skip2/e/cont; skip2/f/cont; skip2/g/cont; skip2/h/cont; skip2/i/cont; skip2/j/cont; skip2/k/cont; skip2/l/cont; skip2/m/cont; skip2/n/cont; skip2/o/cont; skip2/p/cont; skip2/q/cont; skip2/r/cont; skip2/s/cont; skip2/t/cont; skip2/u/cont; skip2/v/cont; skip2/w/cont; skip2/x/cont; skip2/y/cont; skip2/z/cont; skip2/A/cont; skip2/B/cont; skip2/C/cont; skip2/D/cont; skip2/E/cont; skip2/F/cont; skip2/G/cont; skip2/H/cont; skip2/I/cont; skip2/J/cont; skip2/K/cont; skip2/L/cont; skip2/M/cont; skip2/N/cont; skip2/O/cont; skip2/P/cont; skip2/Q/cont; skip2/R/cont; skip2/S/cont; skip2/T/cont; skip2/U/cont; skip2/V/cont; skip2/W/cont; skip2/X/cont; skip2/Y/cont; skip2/Z/cont; skip2/1/cont; skip2/2/cont; skip2/3/cont; skip2/4/cont; skip2/5/cont; skip2/6/cont; skip2/7/cont; skip2/8/cont; skip2/9/cont; skip2/0/cont; skip2/./cont; skip2/ /out; /B/cont; skip2/C/cont; skip2/D/cont; skip2/E/cont; skip2/F/cont; skip2/G/cont; skip2/H/cont; skip2/I/cont; skip2/J/cont; skip2/K/cont; skip2/L/cont; skip2/M/cont; skip2/N/cont; skip2/O/cont; skip2/P/cont; skip2/Q/cont; skip2/R/cont; skip2/S/cont; skip2/T/cont; skip2/U/cont; skip2/V/cont; skip2/W/cont; skip2/X/cont; skip2/Y/cont; skip2/Z/cont; skip2/1/cont; skip2/2/cont; skip2/3/cont; skip2/4/cont; skip2/5/cont; skip2/6/cont; skip2/7/cont; skip2/8/cont; skip2/9/cont; skip2/0/cont; skip2/./cont; skip2/ /out;# # include "mcons.c" # include "ccmn.c" /*int mbuf[1024]; /*INSTR*/ /*int tbuf[36]; /*INSTR*/ int (*acts[])() {0, &coll, &save, &out, &asym, &asw, &csym, &csw, &incl, &decl, &sk2, &sk, &tabs, &semi }; char *tmp[5] {"/tmp/crt0a", "/tmp/crt1a", "/tmp/crt2a", "/tmp/crt3a", "/tmp/crt4a" }; char *ignonl "/usr/lib/aign"; char *gtab "/usr/lib/atab"; main(argc,argv) char *argv[]; { auto i,j,tm1,tm2,tm3; char *fn,*av[8]; /* extern etext; /*INSTR*/ /* monitor(&main,&etext,&mbuf,1024); /*INSTR*/ if(argc < 2) { printf("Usage: cref [-acilonstux123] file1 ...\n"); exit(); } lbuf[4] = '\t'; if(*argv[1] == '-') { j = flags(argv); argv =+ j; argc =- j; } if(argc == 2) single = 1; init(); i = 0; while(++i < argc) { curs[0] = '_'; curs[1] = '\t'; curs[4] = '\t'; cursl = 2; if(fopen(argv[i],ibuf1) < 0) { printf("Can't open %s\n",argv[i]); dexit(); } ibuf = ibuf1; curf[0] = '\t'; curfl = 1; while((curf[curfl] = *argv[i]++) != 0 && curfl <= 8) if(curf[curfl++] == '/') curfl = 1; curf[curfl++] = '\t'; if(curfl == 10) curf[9] = -1; /* printf("%s %d\n",curf,curfl);/*DEBUG*/ lno = 1; driver(); close(file); } for(j = 0; j < 4;) { flsh(j,0); close(tp[j++]); } /* monitor(0); /*INSTR*/ /* dexit(); /*INSTR*/ /* times(tbuf); /*INSTR*/ /* tm1 = tbuf[15]/6; /*INSTR*/ /* tm2 = tbuf[19]/6; /*INSTR*/ /* tm3 = tbuf[23]/6; /*INSTR*/ /* printf("Prep: %d %d %d\n",tm1,tm2,tm3); /*INSTR*/ if(utmp) exit(); fn = "/bin/sort"; av[0] = "sort"; av[2] = "-o"; av[4] = 0; for(i = 0; i < 4; i++) { av[3] = av[1] = tmp[i]; callsys(fn,av); if(utmp) break; } /* times(tbuf); /*INSTR*/ /* tm1 = tbuf[27]/6; /*INSTR*/ /* tm2 = tbuf[31]/6; /*INSTR*/ /* tm3 = tbuf[35]/6; /*INSTR*/ /* printf("Sort: %d %d %d\n",tm1,tm2,tm3); /*INSTR*/ if(usw) { fn = "/usr/bin/upost"; av[0] = "upost"; i = 0; } else { fn = "/usr/bin/crpost"; av[0] = "crpost"; av[1] = cross? "-4x": "-3"; if(single) av[1][1]--; i = 1; } j = -1; while(++j < 4) { av[++i] = tmp[j]; if(utmp) break; } av[++i] = 0; callsys(fn,av); /* times(tbuf); /*INSTR*/ /* tm1 = tbuf[27]/6 - tm1; /*INSTR*/ /* tm2 = tbuf[31]/6 - tm2; /*INSTR*/ /* tm3 = tbuf[35]/6 - tm3; /*INSTR*/ /* printf("Post: %d %d %d\n",tm1,tm2,tm3); /*INSTR*/ dexit(); } driver() { auto p; top: l = -1; while((c = line[++l] = getc(ibuf)) != -1) { if(l >= 131) { printf("Line too long: %d %s\n",lno,curf); dexit(); } if(c & 0200) { printf("Illegal character: %o line %d\n",c,lno); dexit(); } if(fl) { if((*flag[fl])()) continue; } /*printf("cs = %d cc = %c ca = %d\n",cs,c,tab[cs].cl[c]); /*DEBUG*/ if(p = tab[cs].cl[c]) (*acts[p])(); continue; } if(ibuf == ibuf1) return; ibuf = ibuf1; goto top; } init() { int b[3]; auto fi,i; extern coll(),save(),out(),asym(),asw(),csym(),csw(); extern incl(),decl(),sk(),sk2(); extern dexit(); ibuf1 = &ib1; ibuf2 = &ib2; xtab.hptr = &xpsp; xtab.symt = &xssp; xtab.hsiz = PTRX; xtab.ssiz = CHARX; xtab.nsym = 0; xtab.curb = 1; itab.hptr = &ipsp; itab.symt = &issp; itab.hsiz = PTRI; itab.ssiz = CHARI; itab.nsym = 0; itab.curb = 1; if((fi = open(gtab,0)) < 0) { printf("Cannot open grammar table; see lem\n"); dexit(); } i = -1; while(++i < NUMS) if(read(fi,tab[i].cl,256) < 256) { printf("Bad grammar table.\n"); dexit(); } close(fi); if((fi = open(ignonl,0)) < 0) { printf("Cannot open ignore/only file: %s\n",ignonl); dexit(); } if(gtty(fi, b) != -1) { close(fi); compile(); goto on; } if((read(fi,b,6) == 6) && (b[0] == 0100200)) { if(read(fi,itab.hptr,b[1]) < b[1]) { printf("Cannot read ignore/only file: %s\n",ignonl); dexit(); } if(read(fi,itab.symt,b[2]) < b[2]) { printf("Cannot read ignore/only file: %s\n",ignonl); dexit(); } close(fi); } else { close(fi); compile(); } on: if((signal(1,1) & 1) == 0) signal(1,&dexit); if((signal(2,1) & 1) == 0) signal(2,&dexit); if((signal(3,1) & 1) == 0) signal(3,&dexit); /* signal(4,&dexit); signal(5,&dexit); signal(6,&dexit); signal(7,&dexit); signal(8,&dexit); signal(10,&dexit); signal(11,&dexit); signal(12,&dexit); */ if(utmp == 0) { while((tp[4] = creat(tmp[4],0)) < 0) tmp[4][9]++; close(tp[4]); tmp[0][9] = tmp[4][9]; tmp[1][9] = tmp[4][9]; tmp[2][9] = tmp[4][9]; tmp[3][9] = tmp[4][9]; tp[0] = creat(tmp[0],CREATC); tp[1] = creat(tmp[1],CREATC); tp[2] = creat(tmp[2],CREATC); tp[3] = creat(tmp[3],CREATC); } else { if((tp[0] = creat(utmp,CREATC)) < 0) { printf("Can't create user's temp file.\n"); exit(); } } return; } error(a) { printf("Error %d\n",a); dexit(); } dexit() { extern nflush; /* printf("nflush = %d\n",nflush); /*DEBUG*/ if(tp[0] > 0 && utmp == 0) { unlink(tmp[0]); unlink(tmp[1]); unlink(tmp[2]); unlink(tmp[3]); unlink(tmp[4]); } exit(); } callsys(f,v) char f[],*v[]; { int t,status,i; if((t = fork()) == 0) { execv(f,v); printf("Can't find %s\n",f); exit(1); } else { if(t == -1) { printf("Try again\n"); return(1); } } while(t != wait(&status)); /* printf("Status = %o, %s\n",status,f); /*DEBUG*/ if((t = (status & 0377)) != 0) { if(t != 2) { printf("Fatal error in %s\n",f); printf("t = %d\n",t); } dexit(); } return((status>>8) & 0377); } flags(argv) char *argv[]; { int j,xx; char *ap; j = 1; ap = argv[1]; while(*++ap != '\0') { switch(*ap) { default: printf("Unrecognized flag: %c\n",*ap); dexit(); case '1': /* Symbol first */ order = 1; continue; case '2': /* Current file first */ order = 2; continue; case '3': /* Current symbol first */ order = 3; continue; case 'a': /* Assembler */ cflag = 0; continue; case 'c': /* C */ gtab = "/usr/lib/ctab"; if(!xx) ignonl = "/usr/lib/cign"; cflag = 1; continue; case 'e': /* English */ gtab = "/usr/lib/etab"; if(!xx) ignonl = "/usr/lib/eign"; continue; case 'i': /* Ignore file */ if(!xx) { xx = 1; only = 0;  ignonl = argv[++j]; } continue; case 'l': /* Line numbers in col. 3 */ cross = 0; continue; case 'o': /* Only file */ if(!xx) { xx = 1; only = 1; ignonl = argv[++j]; } continue; case 'n': /* No context */ nocont = 1; lbuf[4] = '\n'; continue; case 's': /* Symbols in col. 3 */ cross = 1; continue; case 't': utmp = argv[++j]; tmp[0] = argv[j]; continue; case 'u': /* Unique symbols only */ usw = 1; continue; case 'x': /* C externals */ xsw = 1; gtab = "/usr/lib/ctab"; if(!xx) ignonl = "/usr/lib/cign"; cflag = 1; continue; } } return(j); } compile() { char buf[40],*b; int i,v; fopen(ignonl,ibuf1); b = buf - 1; while((*++b = getc(ibuf1)) != -1) { if(*b == '\n') { *b = '\0'; search(buf,b - buf,&itab,1); b = buf - 1; } else { if(*b == '\t') { v = 0; while((i = getc(ibuf1)) != -1) { if(i == '\n') break; v = v*10 + (i - '0'); } search(buf,b - buf,&itab,v); b = buf - 1; } else { if((b - buf) > 39) { printf("Ignore/only symbol too long"); dexit(); } } } } close(ibuf1); return; } char buf[40],*b; int i,v; fopen(ignonl,ibuf1); b = buf - 1; while((*++b = getc(ibuf1)) != -1) { if(*b == '\n') { *b = '\0'; search(buf,b - buf,&itab,1); b = buf - 1; } else { if(*b == '\t') { v = 0; while((i = getc(ibuf1)) != -1) { if(i == '\n') break; v = v*10 + (i - '0'); } int single; int count; int page; struct { char *beg; int ct; char term; } temp[30]; int pn; int word; int hsw; int t1; int level; int hlevel; int dlevel; int xtrn; int tp[2]; struct { int cl[NUMC]; } tab[NUMS]; int coll(); int save(); int out(); int hyphen(); int hyp1(); int hyp2(); int pno(); int error(); char line[300]; int l; int lno; char c; int cursl; char curs[9]; int curfl; char curf[10]; int usw; int xsw; int only; int cross; int file; int cs; int (*flag[8])(); int fl; char gch[8];  struct htab { int hsiz; int ssiz; int nsym; int curb; int *hptr; char *symt; }; struct htab itab; int ipsp[PTRI]; char issp[CHARI]; int ib1[259]; char *ibuf; char *ibuf1; char mone; int order; int ssw; int type; char *utmp; ve(); int out(); int hyphen(); int hyp1(); int hyp2(); int pno(); int error(); char line[300]; int l; int lno; char c; int cursl; char curs[9]; int curfl; char curf[10]; int usw; int xsw; int only; int cross; int file; int cs; int (*flag[8])(); int fl; char gch[8]; # define NUMA 14 # define NUMC 128 # define NUMS 3 # define SIZA 8 # define SIZC 2 # define SIZS 8 # define PTRI 509 # define CHARI 4000 # define PTRX 5147 # define CHARX 40000 # define CONT 0 # define COLL 1 # define SAVE 2 # define OUT 3 # define EGOBL 4 # define SHARP 5 # define PNO 6 # define SKIP 0 # define COLLECT 1 # define SKIP2 2 #define CREATC 0644 ; int cursl; char curs[9]; int curfl; char curf[10]; int usw; int xsw; int only; int cross; int file; int cs; int (*flag[8])(); int fl; char gch[8]; the of and to a in that is was he for it with as his on be at by i this had not are but from or have an they which one you were her all she there would their we him been has when who will more no if out so said what up its about into than them can only other new some could time these two may then do first any my now such like our over man me even most made after also did many before must through back years where much your way well down should because each just those people mr how too little state good very make world still own see men work long get here between both life being under never day same another know while last might us great old year off come since against go came right used take three o if out so said what up its about into than them can only other new some could time these two may then do first any my now such like our over man me even most made after also did many before must through back years where much your way well down should because each just those people mr how too little state good very skip collect save skip2 cont coll save out egobl hyphen pno skip//pno; skip/ /out; skip/a/coll; skip/b/coll; skip/c/coll; skip/d/coll; skip/e/coll; skip/f/coll; skip/g/coll; skip/h/coll; skip/i/coll; skip/j/coll; skip/k/coll; skip/l/coll; skip/m/coll; skip/n/coll; skip/o/coll; skip/p/coll; skip/q/coll; skip/r/coll; skip/s/coll; skip/t/coll; skip/u/coll; skip/v/coll; skip/w/coll; skip/x/coll; skip/y/coll; skip/z/coll; skip/A/coll; skip/B/coll; skip/C/coll; skip/D/coll; skip/E/coll; skip/F/coll; skip/G/coll; skip/H/coll; skip/I/coll; skip/J/coll; skip/K/coll; skip/L/coll; skip/M/coll; skip/N/coll; skip/O/coll; skip/P/coll; skip/Q/coll; skip/R/coll; skip/S/coll; skip/T/coll; skip/U/coll; skip/V/coll; skip/W/coll; skip/X/coll; skip/Y/coll; skip/Z/coll; collect/'/cont; collect/-/hyphen; collect/ /out; collect/a/cont; collect/b/cont; collect/c/cont; collect/d/cont; collect/e/cont; collect/f/cont; collect/g/cont; collect/h/cont; collect/i/cont; collect/j/cont; collect/k/cont; collect/l/cont; collect/m/cont; collect/n/cont; collect/o/cont; collect/p/cont; collect/q/cont; collect/r/cont; collect/s/cont; collect/t/cont; collect/u/cont; collect/v/cont; collect/w/cont; collect/x/cont; collect/y/cont; collect/z/cont; collect/A/cont; collect/B/cont; collect/C/cont; collect/D/cont; collect/E/cont; collect/F/cont; collect/G/cont; collect/H/cont; collect/I/cont; collect/J/cont; collect/K/cont; collect/L/cont; collect/M/cont; collect/N/cont; collect/O/cont; collect/P/cont; collect/Q/cont; collect/R/cont; collect/S/cont; collect/T/cont; collect/U/cont; collect/V/cont; collect/W/cont; collect/X/cont; collect/Y/cont; collect/Z/cont; skip2/a/coll; skip2/b/coll; skip2/c/coll; skip2/d/coll; skip2/e/coll; skip2/f/coll; skip2/g/coll; skip2/h/coll; skip2/i/coll; skip2/j/coll; skip2/k/coll; skip2/l/coll; skip2/m/coll; skip2/n/coll; skip2/o/coll; skip2/p/coll; skip2/q/coll; skip2/r/coll; skip2/s/coll; skip2/t/coll; skip2/u/coll; skip2/v/coll; skip2/w/coll; skip2/x/coll; skip2/y/coll; skip2/z/coll; skip2/A/coll; skip2/B/coll; skip2/C/coll; skip2/D/coll; skip2/E/coll; skip2/F/coll; skip2/G/coll; skip2/H/coll; skip2/I/coll; skip2/J/coll; skip2/K/coll; skip2/L/coll; skip2/M/coll; skip2/N/coll; skip2/O/coll; skip2/P/coll; skip2/Q/coll; skip2/R/coll; skip2/S/coll; skip2/T/coll; skip2/U/coll; skip2/V/coll; skip2/W/coll; skip2/X/coll; skip2/Y/coll; skip2/Z/coll; p/coll; skip2/q/coll; skip2/r/coll; skip2/s/coll; skip2/t/coll; skip2/u/coll; skip2/v/coll; skip2/w/coll; skip2/x/coll; skip2/y/coll; skip2/z/coll; skip2/A/coll; skip2/B/coll; skip2/C/coll;# # include "econs.h" # include "ecmn.h" /*int mbuf[1024]; /*INSTR*/ /*int tbuf[12]; /*INSTR*/ int (*acts[])() {0, &coll, &save, &out, &error, &hyphen, &pno }; char *tmp[2] {"/tmp/crt0a", "/tmp/crt1a" }; char *ignonl "/usr/lib/eign"; char *gtab "/usr/lib/etab"; main(argc,argv) char *argv[]; { auto i,j,tm1,tm2,tm3; char *fn,*av[8]; /* extern etext; /*INSTR*/ /* monitor(&main,&etext,&mbuf,1024); /*INSTR*/ if(*argv[1] == '-') { j = flags(argv); argv =+ j; argc =- j; }  if(argc == 2) single = 1; init(); i = 0; if(argc == 1) { *ibuf1 = 0; curfl = 2; curf[0] = '_'; curf[1] = '\t'; goto pipe; } while(++i < argc) { curs[4] = '\t'; if(fopen(argv[i],ibuf1) < 0) { printf("Can't open %s\n",argv[i]); dexit(); } curfl = 0; while((curf[curfl] = *argv[i]++) != 0 && curfl <=8) if(curf[curfl++] == '/') curfl = 0; curf[curfl++] = '\t'; if(curfl == 8) curf[8] = -1; pipe: ibuf = ibuf1; lno = 1; driver(); close(file); } flsh(0); close(tp[0]); /* monitor(0); /*INSTR*/ /* dexit(); /*INSTR*/ /* times(tbuf); /*INSTR*/ /* tm1 = tbuf[0]/6; /*INSTR*/ /* tm2 = tbuf[1]/6; /*INSTR*/ /* printf("Prep: %d %d\n", tm1, tm2); /*INSTR*/ /* exit(); /*DEBUG*/ fn = "/bin/sort"; av[0] = "sort"; av[1] = tmp[0]; av[2] = "-o"; av[3] = tmp[0]; av[4] = 0; callsys(fn, av); /* times(tbuf); /*INSTR*/ /* tm1 = tbuf[3]/6; /*INSTR*/ /* tm2 = tbuf[5]/6; /*INSTR*/ /* printf("Sort: %d %d\n", tm1, tm2); /*INSTR*/ if(usw) { fn = "/usr/bin/upost"; av[0] = "upost"; i = 0; } else if(count) { fn = "count"; av[0] = "count"; i = 0; } else { fn = "/usr/bin/crpost"; av[0] = "crpost"; if(single) av[1] = "-E2"; else av[1] = "-E3"; i = 1; } av[++i] = tmp[0]; av[++i] = 0; callsys(fn,av); /* times(tbuf); /*INSTR*/ /* tm1 = tbuf[3]/6 - tm1; /*INSTR*/ /* tm2 = tbuf[5]/6 - tm2; /*INSTR*/ /* printf("Post: %d %d\n", tm1, tm2); /*INSTR*/ dexit(); } driver() { auto p; top: l = -1; while((c = line[++l] = getc(ibuf)) != -1) { /* printf("driver: c = %o l = %d\n",c,l); /*DEBUG*/ if(l >= 299) { printf("Line too long: %d.\n",lno); dexit(); } if(c & 0200) { printf("Illegal character: %o line %d\n",c,lno); dexit(); } if(fl) { if((*flag[fl])()) continue; } /*printf("cs = %d cc = %c ca = %d\n",cs,c,tab[cs].cl[c]); /*DEBUG*/ if(p = tab[cs].cl[c]) (*acts[p])(); continue; } if(ibuf == ibuf1) return; ibuf = ibuf1; goto top; } init() { int b[3]; auto fi,i; extern coll(),save(),out(),asym(),asw(),csym(),csw(); extern incl(),decl(),sk(),sk2(); extern dexit(); ibuf1 = &ib1; if((fi = open(gtab,0)) < 0) { printf("Cannot open grammar table; see lem\n"); dexit(); } i = -1; while(++i < NUMS) if(read(fi,tab[i].cl,256) < 256) { printf("Bad grammar table; see lem\n"); dexit(); } close(fi); if(signal(1,1) != 1) signal(1,&dexit); if(signal(2,1) != 1) signal(2,&dexit); if(signal(3,1) != 1) signal(3,&dexit); if(!utmp) { while((tp[1] = creat(tmp[1],0)) < 0) tmp[1][9]++; close(tp[1]); tmp[0][9] = tmp[1][9]; } tp[0] = creat(tmp[0],CREATC); if(count) return; itab.hptr = &ipsp; itab.symt = &issp; itab.hsiz = PTRI; itab.ssiz = CHARI; itab.nsym = 0; itab.curb = 1; if((fi = open(ignonl,0)) < 0) { printf("Cannot open ignore/only file.\n"); dexit(); } if((read(fi,b,6) == 6) && (b[0] == 0100200)) { if(read(fi,itab.hptr,b[1]) < b[1]) { printf("Cannot read ignore/only file.\n"); dexit(); } if(read(fi,itab.symt,b[2]) < b[2]) { printf("Cannot read ignor/only file.\n"); dexit(); } close(fi); } else { close(fi); compile(); } return; } error(a) { printf("Error %d\n",a); dexit(); } dexit() { extern nflush; /* printf("nflush = %d\n",nflush); /*DEBUG*/ if(tp[0] > 0 && utmp == 0) { unlink(tmp[0]); unlink(tmp[1]); } exit(); } callsys(f,v) char f[],*v[]; { int t,status,i; if((t = fork()) == 0) { for(i = 1; i <= 12; i++) signal(i,0); execv(f,v); printf("Can't find %s\n",f); exit(1); } else { if(t == -1) { printf("Try again\n"); return(1); } } while(t != wait(&status)); /* printf("Status = %o, %s\n",status,f); /*DEBUG*/ if((t = (status & 0377)) != 0) { if(t != 2) { printf("Fatal error in %s\n",f); printf("t = %d\n",t); } dexit(); } return((status>>8) & 0377); } flags(argv) char *argv[]; { int j,xx; char *ap; j = 1; ap = argv[1]; while(*++ap != '\0') { switch(*ap) { default: printf("Unrecognized flag: %c\n",*ap); dexit(); case 'c': count = 1; continue; case 'i': /* Ignore file */ if(!xx) { xx = 1; only = 0; ignonl = argv[++j]; } continue; case 'o': /*only file*/ if(!xx) { xx = 1; only = 1; ignonl = argv[++j]; } continue; case 'p': page = 1; continue; case 't': utmp = argv[++j]; tmp[0] = argv[j]; continue; case 'u': /* Unique symbols only */ usw = 1; continue; case 'w': /* Word list only */ word = 1; continue; } } return(j); } compile() { char buf[40],*b; int i,v; fopen(ignonl,ibuf1); b = buf - 1; while((*++b = getc(ibuf1)) != -1) { if(*b == '\n') { *b = '\0'; search(buf,b - buf,&itab,1); b = buf - 1; } else { if(*b == '\t') { v = 0; while((i = getc(ibuf1)) != -1) { if(i == '\n') break; v = v*10 + (i - '0'); } search(buf,b - buf,&itab,v); b = buf - 1; } else { if((b - buf) > 39) { printf("Ignore/only symbol too long.\n"); dexit(); } } } } close(ibuf1); return; } har buf[40],*b; i# # include "econs.h" # include "ecmn.h" # define SKIP 0 # define COLLECT 1 # define SKIP2 2 char mone -1; int tlno 1; coll() { cs = COLLECT; temp[t1].beg = &line[l]; return; } save() { extern only; char *pt1,*pt2,cbuf[30]; int a,tt,val; cs = SKIP; line[l] = '\0'; temp[t1].ct = &line[l] - temp[t1].beg; if(!count) if(temp[t1].ct == 1) goto no; pt1 = temp[t1].beg-1; pt2 = cbuf-1; while(*++pt2 = *++pt1) if(*pt2 >= 'A' && *pt2 <= 'Z') *pt2 =| 040; if(count) goto yes; val = search(cbuf,temp[t1].ct,&itab,0); if(!val == !only) goto yes; no: line[l] = c; return(0); yes: if(count == 0) { tt = t1; while(tt) if(comp(temp[t1].beg,temp[--tt].beg)) goto no; } temp[t1++].term = c; return(1); } out() { auto i,ct,t2; char *b,*e; if(cs == COLLECT) save(); ct = t1; while(ct--) temp[ct].beg[temp[ct].ct] = temp[ct].term; t2 = t1 - 1; while(t1--) { /*printf("t1 = %d beg = %o ct = %d\n",t1,temp[t1].beg,temp[t1].ct); /* DEBUG */ if((ct = temp[t1].ct) >= 15) { ct = 15; } put(temp[t1].beg,ct); if(count) { put("\n", 1); continue; } put("\t",1); if(!page) { if(!single) put(curf,curfl); conf(lno,4,curs); put(curs,4); } else { conf(pn,4,curs); put(curs,4); } if(word == 0) { put("\t",1); if(t1 >= 1) b = temp[t1-1].beg; else b = line; if(t2 > t1) e = temp[t1+1].beg + temp[t1+1].ct; else e = &line[l]; /*printf("e = %o b = %o\n",e,b); /*DEBUG*/ put(b,e-b); } put("\n",1); } t1 = 0; l = -1; lno =+ tlno; tlno = 1; cs = SKIP; return; } search(symbol,length,params,install) char *symbol; int length; struct htab *params; int install; { char *sp,*p; static int *hptr,hsiz,nsym; static char *ssiz; static int curb; static char *symt; auto h,i,j,k; if(hptr != params->hptr) { hptr = params->hptr; hsiz = params->hsiz; symt = params->symt; ssiz = params->ssiz; curb = params->curb; nsym = params->nsym; } symbol[length] = '\0'; /*printf("ssiz = %d; nsym = %d; %s\n", ssiz, nsym, symbol);/*DEBUG*/ sp = symbol; i = length; h = 1; while(i--) h =* *sp++; if(h == 0100000) { h = 1; } else { h = h<0?(-h)%hsiz:h%hsiz; } if(h == 0) h++; /* printf("%s %d\n",symbol,h); /*DEBUG*/ while((p = &symt[hptr[h]]) > symt) { j = length + 2; sp = symbol; while(--j) { if(*p++ != *sp++) goto no; } return(*p); no: h = (h + h)%hsiz; } if(install) { if(++nsym >= hsiz) { printf("Too many symbols in ignore/only file.\n"); dexit(); } hptr[h] = curb; length++; if((curb + length) >= ssiz) { printf("i/o file too big; ssiz = %d\n", ssiz); dexit(); } while(length--) symt[curb++] = *symbol++; symt[curb++] = install; params->curb = curb; params->nsym = nsym; } return(0); } conf(n,width,buf) char *buf; { auto i,a; i = width; while(i--) buf[i] = ' '; buf[(a = n/10)?conf(a,--width,buf):--width] = n%10 + '0'; return(++width); } comp(a,b) char *a; char *b; { a--; b--; while(*++a == *++b) if(*a == '\0') return(1); return(0); } hyphen() { /* printf("hyphen\n"); /*DEBUG*/ if(gch[fl] == 0) flag[++fl] = &hyp1; return(1); } hyp1() { /* printf("hyp1 c = %o\n",c); /*DEBUG*/ if(c != '\n') { fl--; return(0); } else { l =- 2; flag[fl] = &hyp2; hsw = 1; return(1); } } hyp2() { /* printf("hyp2 c = %o l = %d\n",c,l); /*DEBUG*/ if(hsw && (tab[2].cl[c] == 0)) { l--; if(c == 3) pno(); if(c == '\n') tlno++; return(1); } hsw = 0; if(tab[cs].cl[c]) { line[l] = '\n'; out(); fl--; return(0); } return(1); } pno() { if(flag[fl] != &pno) { flag[++fl] = &pno; pn = 0; return(1); } if(c == '\n') { fl--; out(); return(1); } pn = pn*10 + c - '0'; return(1); } fl--; return(0); } else { l =- 2; flag[fl] = &hyp2; hsw = 1; return(1); } } hyp2() { /* printf("hyp2 c = %o l = %d\n",c,l); /*DEBUG*/ if(hsw && (tab[2].cl[c] == 0)) { l--; if(c == 3) pno(); if(c == '\n') tlno++; return(1); } hsw = 0; if(tab[cs].cl[c]) { line[l] = '\n'; out(); fl--; return(0); } return(1); } pno() { int optr; char obuf[512]; int nflush; put(string,n) char *string; { extern utmp; int i; char *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr + n - 512) >= 0) { n =- i; o = &obuf[optr] -1; while(--n >= 0) *++o = *++string; optr = 512; flsh(1); n = i; } o = &obuf[optr] - 1; optr =+ n; while(--n >= 0) { *++o = *++string; } return(0); } flsh(fil) { extern tp[],utmp; if(optr <= 0) return(optr); nflush++; if(write(tp[0],obuf,optr) != optr) return(-1); optr = 0; return(0); } sh; put(string,n) char *string; { extern utmp; int i; char *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr + n - 512) >= 0) { n =- i; o = &obuf[optr] -1; while(--n >= 0) *++o = *++string; optr = 512; flsh(1); n = i; } o = &obuf[optr] - 1; optr =+ n; while(--n >= 0) { *++o = *++string; } return(0); } flsh(fil) { extern tp[],utmp; if(optr <= 0) return(optr); nflush++; if(write(tp[0],obuf,optr) != optr) re# # include "mcons.c" char ib1[518]; char *ibuf &ib1; struct htab { int hsiz; int ssiz; int nsym; int curb; int *hptr; char *symt; }; struct htab itab; struct htab xtab; int ipsp[PTRI]; char issp[CHARI]; search(symbol,length,params,install) char *symbol; int length; struct htab *params; int install; { char *sp,*p; int curb,*hptr,hsiz,nsym,ssiz; char *symt; auto h,i,j,k; hptr = params->hptr; hsiz = params->hsiz; symt = params->symt; ssiz = params->ssiz; curb = params->curb; nsym = params->nsym; symbol[length] = '\0'; sp = symbol; i = length; h = 1; while(i--) h =* *sp++; if(h == 0100000)h = 1; h = h<0?(-h)%hsiz:h%hsiz; if(h == 0) h++; /* printf("%s %d\n",symbol,h); /*DEBUG*/ while((p = &symt[hptr[h]]) > symt) { j = length + 1; sp = symbol; while(j--) { if(*p++ != *sp++) goto no; } return(*p); no: h = (h + h)%hsiz; } if(install) { if(++nsym >= hsiz) err("too many","symbols"); hptr[h] = curb; length++; if((curb + length) >= ssiz) err("too many","chars"); while(length--) symt[curb++] = *symbol++; symt[curb++] = install; params->curb = curb; params->nsym = nsym; } return(0); } main(argc,argv) char **argv; { auto ifile,ofile,i,c,error,val; char t[20]; if(argc != 3)exit(); ifile = fopen(argv[1],ibuf); if(ifile < 0)err("open",argv[1]); ofile = creat(argv[2],0644); if(ofile < 0)err("creat",argv[2]); xtab.hptr = &ipsp; xtab.symt = &issp; xtab.hsiz = PTRI; xtab.ssiz = CHARI; xtab.nsym = 0; xtab.curb = 1; i = xtab.hsiz; while(i)xtab.hptr[--i] = 0; i = -1; while((t[++i] = getc(ibuf)) >= 0){ if(t[i] == '\n'){ i = search(t,i,&xtab,1); i = -1; } else { if(t[i] == '\t') { val = gen(); search(t,i,&xtab,val); i = -1; } } } /* printf("collisions = %d\nsymbols = %d\n",ncol,nsym); /*INSTR*/ i = 0100200; error = write(ofile,&i,2); if(error < 0)err("write",argv[2]); i = 2*xtab.hsiz; error = write(ofile,&i,2); if(error < 0)err("write",argv[2]); error = write(ofile,&xtab.ssiz,2); if(error < 0)err("write",argv[2]); error = write(ofile,xtab.hptr,i); if(error < 0)err("write",argv[2]); error = write(ofile,xtab.symt,xtab.ssiz); if(error < 0)err("write",argv[2]); return; } err(a,b) char *a,*b; { printf("%s %s\n",a,b); exit(); } gen() { auto i,v; v = 0; while((i = getc(ibuf)) != -1) { if(i == '\n') break; v = v*10 + (i - '0'); } return(v); } argv[2]); i = 2*xtab.hsiz; error = write(ofile,&i,2); if(error < 0)err("write",argv[2]); error = write(ofile,&xtab.ssiz,2); if(error # define NUMA 14 # define NUMC 128 # define NUMS 3 # define SIZA 8 # define SIZC 2 # define SIZS 8 # define PTRI 509 # define CHARI 4000 # define PTRX 509 # define CHARX 4000 # define CONT 1 # define COLL 2 # define SAVE 3 # define OUT 4 # define ASYM 5 # define ASW 6 # define CSYM 7 # define CSW 8 # define INCL 9 # define DECL 10 # define SK2 11 # define SK 12 # define TABS 13 # define SEMI 14 # define SHARP 15 # define SKIP 0 # define COLLECT 1 # define SKIP2 2 #define CREATC 0644 tab.ssiz,2); if(error # include "mcons.c" struct { int cl[NUMC]; }tab[NUMS]; char state[NUMS][SIZS]; char class[NUMC][SIZC]; char act[NUMA][SIZA]; char def[NUMS][SIZA]; char temp[SIZA]; char *st[NUMS]; char *df[NUMS]; char *cl[NUMC]; char *ac[NUMA]; int t1; int t2; main(argc,argv) char **argv; { extern fin; char fl,nlfl,c,bfl,fo,brk; int cs,ca,cc,i,j,cd; if(argc != 3) { printf("Usage: mtab input output\n"); exit(); } if((fo = creat(argv[2],0644)) < 0) { printf("Output file.\n"); exit(); } if((fin = open(argv[1],0)) < 0) { printf("Input file.\n"); exit(); } nlfl = 1; i = -1; while(brk = rword()) { switch (brk) { case '\n': if(nlfl) { move(temp,state[++i]); st[i] = &state[i]; } else { move(temp,def[i]); df[i] = &def[i]; nlfl = 1; } continue; case ' ': if(nlfl) { move(temp,state[++i]); st[i] = &state[i]; nlfl = 0; } else { error(7); } continue; } } i = 128; while(--i) { class[i][0] = i; class[i][1] = '\0'; cl[i] = &class[i]; } cl[0] = &class[0]; bfl = nlfl = 0; t1 = 0; t2 = -1; while(c = getchar()) { switch(c) { default: if(t1 >= NUMA) error(4); bfl = nlfl = 0; act[t1][++t2<8?t2:7] = c; continue; case '\n': if(nlfl) break; nlfl = 1; case ' ': if(bfl) continue; bfl = 1; act[t1][++t2<8?t2:7] = '\0'; ac[t1] = &act[t1]; t1++; t2 = -1; continue; } break; } if(c == '\0') exit(); i = -1; while(++i < NUMS) { if(df[i]) { cd = find(ac,df[i],NUMA); j = -1; while(++j < NUMC) tab[i].cl[j] = cd; } } fl = 0; i = -1; while(c = getchar()) { switch(c) { case '\\': temp[++i] = getchar(); continue; case '\n': if(fl != 1) continue; default: temp[++i] = c; continue; case '/': temp[++i] = '\0'; i = -1; switch(fl) { case 0: cs = find(st,temp,NUMS); fl = 1; continue; case 1: cc = find(cl,temp,NUMC); fl = 2; continue; default: error(1); } case ';': if(fl != 2) error(2); temp[++i] = '\0'; i = -1; ca = find(ac,temp,NUMA); /*printf("%o %o %o\n",cs,cc,ca); /*DEBUG*/ tab[cs].cl[cc] = ca; fl = 0; continue; } } i = -1; while(++i < NUMS) write(fo,tab[i].cl,256); } error(a) { printf("Error %d\n",a); exit(); } find(a,b,c) char (*a[])[1]; char b[]; int c; { int i,j; /* printf("%s\n",b); /*DEBUG*/ i = -1; while(++i < c) { /* printf(" %s\n",a[i]); /*DEBUG*/ j = 0; /* printf("b = %c\ta = %c\n",b[0],(*a[i])[0]); /*DEBUG*/ while(b[j] == (*a[i])[j]) { if(b[j] == '\0') goto found; j++; } } found: return(i); } rword() { char c; int ct; ct = -1; while(c = getchar()) { switch(c) { default: temp[++ct] = c; continue; case '\n': if(ct == -1) return('\0'); case ' ': temp[++ct] = '\0'; return(c); } } } move(a,b) char *a; char *b; { while((*b++ = *a++) != '\0'); return; } c) { /* printf(" %s\n",a[i]); /*DEBUG*/ j = 0; /*int bct[4]; int optr[4]; char bsp[2048]; char *obuf[4] {bsp, bsp + 512, bsp + 1024, bsp + 1536 }; int nflush; put(fil,string,n) char *string; { extern utmp; int i; char *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr[fil] + n - 512) >= 0) { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0) *++o = *++string; optr[fil] = 512; flsh(fil); n = i; } o = &obuf[fil][optr[fil]] - 1; optr[fil] =+ n; while(--n >= 0) { *++o = *++string; } return(0); } flsh(fil) { extern tp[],utmp; if(optr[fil] <= 0) return(optr[fil]); if(bct[fil]++ >= 128 && utmp == 0) { printf("Wraparound temp file %d\n",fil); dexit(); } nflush++; if(write(tp[fil],obuf[fil],optr[fil]) != optr[fil]) return(-1); optr[fil] = 0; return(0); } { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0) *++o = *++string; optr[fil] = 512; flsh(fil); n = i; } o = &obuf[fil][optr[fil]] - 1; optr[fil] =+ n; while(--n >= 0) { *++o = *++string; } re/*int mbuf[1024]; /*INSTR*/ int psw 1; int initf 1; main(argc, argv) char *argv[]; { auto f,fct,file; if(argc < 2) { printf("Usage: cpost [-d] file1 file2 ...\n"); exit(); } if(*argv[1] == '-') { fct = argv[1][1] - '0'; if((fct < 1) || (fct > 9)) { printf("-d: 0 < d < 10\n"); exit(); } argv++; argc--; } else { fct = 1; } f = 0; while(++f < argc) { file = open(argv[f], 0); edl(file, fct); close(file); psw = 0; } flsh(0); exit(); } int lno 1; edl(file) { auto t,l; char static buf[20],fld[20],line[200]; char c; field: t = -1; while(((buf[++t] = get(file)) != '\t') && (buf[t] != -1)) if(buf[t] == '\0') goto done; if((c = buf[t]) == -1) c = ' '; buf[t] = '\0'; if(comp(buf,fld)) { lno++; goto junk; } else { if(lno == 0) { put(0,line,++l); } l = copy(buf,line); copy(buf,fld); line[--l] = c; lno = 0; goto fill; } fill: while((line[++l] = get(file)) != '\n') { if(line[l] == -1) line[l] = ' '; if(line[l] == '\0') goto done; } goto field; junk: while((*line = get(file)) != '\n') if(*line == '\0') goto done; goto field; done: if(lno == 0) put(0,line,++l); lno = 1; return(0); } gfld(file, buf) char *buf; { char c; buf--; while(*++buf = get(file)) { if((*buf == '\t') || (*buf == '\n')) { c = *buf; *buf = '\0'; return(c); } else { continue; } } return('\0'); } copy(a, b) char *a,*b; { char *c; b--; c = --a; while(*++b = *++a); return(a - c); } comp(a, b) char *a, *b; { /* printf("comp: %s %s\n",a,b); /*DEBUG*/ a--; b--; while(*++a == *++b) { if(*a == '\0') return(1); } return(0); } char buf[512]; int nread 1; get(ifile) int ifile; { char static *ibuf; if(--nread){ return(*ibuf++); } if(nread = read(ifile,buf,512)){ if(nread < 0)goto err; ibuf = buf; return(*ibuf++); } nread = 1; return(0); err: nread = 1; printf("read error\n"); return(0); } int tp[1] 1; int optr[4]; char bsp[512]; char *obuf[1] bsp; int nflush; put(fil,string,n) char *string; { int i; char *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr[fil] + n - 512) >= 0) { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0) *++o = *++string; optr[fil] = 512; flsh(fil); n = i; } o = &obuf[fil][optr[fil]] - 1; optr[fil] =+ n; while(--n >= 0) { *++o = *++string; } return(0); } flsh(fil) { extern tp[]; if(optr[fil] <= 0) return(optr[fil]); nflush++; if(write(tp[fil],obuf[fil],optr[fil]) != optr[fil]) return(-1); optr[fil] = 0; return(0); } *o; /*printf("%d %c %d\n",fil,*string,n);/*DEBUG*/ string--; if((i = optr[fil] + n - 512) >= 0) { n =- i; o = &obuf[fil][optr[fil]] -1; while(--n >= 0) *++o = *++string; optr[fil] = 512; flsh(fil); n = i; } o = &obuf[fil][optr[fil]] - 1; optr[fil] =+ n; while(--n >= 0) { *++o = *++string; } return(0); } flsh(fil) { extern tp[]; if(optr[fil] <= 0) return(optr[fil]); nflush++; if(write(tp[fil],obuf[fil],optr[fil]) != optr[fil]) return(-1); optr[fil] = 0              # # define UMINUS 257 # define LETTER 258 # define DIGIT 259 # define SQRT 260 # define LENGTH 261 # define _IF 262 # define FFF 263 # define EQ 264 # define _WHILE 265 # define _FOR 266 # define NE 267 # define LE 268 # define GE 269 # define INCR 270 # define DECR 271 # define _RETURN 272 # define _BREAK 273 # define _DEFINE 274 # define BASE 275 # define OBASE 276 # define SCALE 277 # define EQPL 278 # define EQMI 279 # define EQMUL 280 # define EQDIV 281 # define EQREM 282 # define EQEXP 283 # define _AUTO 284 # define DOT 285 # define QSTR 286 char cary[1000], *cp { cary }; char string[1000], *str {string}; int crs '0'; int rcrs '0'; /* reset crs */ int bindx 0; int lev 0; int ln; char *ss; int bstack[10] { 0 }; char *numb[15] { " 0", " 1", " 2", " 3", " 4", " 5", " 6", " 7", " 8", " 9", " 10", " 11", " 12", " 13", " 14" }; int *pre, *post; #define yyclearin yychar = -1 #define yyerrok yyerrflag = 0 extern int yychar, yyerrflag; int yyval 0; int *yypv; int yylval 0; yyactr(__np__){ switch(__np__){ case 2: output( yypv[2] ); break; case 3:{ bundle( pre, yypv[7], post ,"0",numb[lev],"Q"); conout( yyval, yypv[2] ); rcrs = crs; output( "" ); lev = bindx = 0; } break; case 6:{ bundle( yypv[1], "ps." ); } break; case 7:{ bundle( "" ); } break; case 8:{ bundle("[",yypv[1],"]P");} break; case 9:{ bundle( yypv[3], "s", yypv[1] ); } break; case 10:{ bundle( yypv[6], yypv[3], ":", geta(yypv[1])); } break; case 11:{ bundle( "l", yypv[1], yypv[3], yypv[2], "s", yypv[1] ); } break; case 12:{ bundle(yypv[3], ";", geta(yypv[1]), yypv[6], yypv[5], yypv[3], ":", geta(yypv[1]));} break; case 13:{ bundle( numb[lev-bstack[bindx-1]], "Q" ); } break; case 14: bundle( yypv[3], post, numb[lev], "Q" ); break; case 15: bundle( "0", post, numb[lev], "Q" ); break; case 16: bundle("0",post,numb[lev],"Q"); break; case 17: bundle( yypv[3], "k"); break; case 18: bundle("K",yypv[3],yypv[2],"k"); break; case 19: bundle(yypv[3], "i"); break; case 20: bundle("I",yypv[3],yypv[2],"i"); break; case 21: bundle(yypv[3],"o"); break; case 22: bundle("O",yypv[3],yypv[2],"o"); break; case 23:{ yyval = yypv[2]; } break; case 24:{ bundle("f"); } break; case 25:{ bundle("c"); } break; case 26:{ conout( yypv[7], yypv[2] ); bundle( yypv[5], yypv[2], " " ); } break; case 27:{ bundle( yypv[6], yypv[4], yypv[2] ); conout( yyval, yypv[2] ); bundle( yypv[4], yypv[2], " " ); } break; case 28:{ bundle( yypv[7], yypv[5], "s.", yypv[3], yypv[2] ); conout( yyval, yypv[2] ); bundle( yypv[1], "s.", yypv[3], yypv[2], " " ); } break; case 29:{ bundle(yypv[4],"S",yypv[2]); } break; case 30:{ yyval = "+"; } break; case 31:{ yyval = "-"; } break; case 32:{ yyval = "*"; } break; case 33:{ yyval = "/"; } break; case 34:{ yyval = "%%"; } break; case 35:{ yyval = "^"; } break; case 36:{ yyval = yypv[3]; } break; case 37:{ --bindx; } break; case 39:{ bundle( yypv[1], yypv[3] ); } break; case 40:{ln++;} break; case 42: bundle( yypv[1], yypv[3], "=" ); break; case 43: bundle( yypv[1], yypv[3], ">" ); break; case 44: bundle( yypv[1], yypv[3], "<" ); break; case 45: bundle( yypv[1], yypv[3], "!=" ); break; case 46: bundle( yypv[1], yypv[3], "!>" ); break; case 47: bundle( yypv[1], yypv[3], "!<" ); break; case 48: bundle( yypv[1], " 0!=" ); break; case 49: bundle( yypv[1], yypv[3], "+" ); break; case 50: bundle( yypv[1], yypv[3], "-" ); break; case 51: bundle( " 0", yypv[2], "-" ); break; case 52: bundle( yypv[1], yypv[3], "*" ); break; case 53: bundle( yypv[1], yypv[3], "/" ); break; case 54: bundle( yypv[1], yypv[3], "%%" ); break; case 55: bundle( yypv[1], yypv[3], "^" ); break; case 56:{ bundle(yypv[3], ";", geta(yypv[1])); } break; case 57: bundle( "l", yypv[1], "d1+s", yypv[1] ); break; case 58: bundle( "l", yypv[2], "1+ds", yypv[2] ); break; case 59: bundle( "l", yypv[2], "1-ds", yypv[2] ); break; case 60: bundle( "l", yypv[1], "d1-s", yypv[1] ); break; case 61: bundle(yypv[3],";",geta(yypv[1]),"d1+",yypv[3],":",geta(yypv[1])); break; case 62: bundle(yypv[4],";",geta(yypv[2]),"1+d",yypv[4],":",geta(yypv[2])); break; case 63: bundle(yypv[3],";",geta(yypv[1]),"d1-",yypv[3],":",geta(yypv[1])); break; case 64: bundle(yypv[4],";",geta(yypv[2]),"1-d",yypv[4],":",geta(yypv[2])); break; case 65: bundle("Kd1+k"); break; case 66: bundle("K1+dk"); break; case 67: bundle("Kd1-k"); break; case 68: bundle("K1-dk"); break; case 69: bundle("Id1+i"); break; case 70: bundle("I1+di"); break; case 71: bundle("Id1-i"); break; case 72: bundle("I1-di"); break; case 73: bundle("Od1+o"); break; case 74: bundle("O1+do"); break; case 75: bundle("Od1-o"); break; case 76: bundle("O1-do"); break; case 77: bundle( yypv[3], "l", getf(yypv[1]), "x" ); break; case 78: bundle( "l", getf(yypv[1]), "x" ); break; case 79:{ bundle( " ", yypv[1] ); } break; case 80:{ bundle( " .", yypv[2] ); } break; case 81:{ bundle( " ", yypv[1], ".", yypv[3] ); } break; case 82:{ bundle( " ", yypv[1], "." ); } break; case 83:{ yyval = "l."; } break; case 84: { bundle( "l", yypv[1] ); } break; case 85:{ bundle( yypv[3], "ds", yypv[1] ); } break; case 86:{ bundle( "l", yypv[1], yypv[3], yypv[2], "ds", yypv[1] ); } break; case 87: { bundle(yypv[6],"d",yypv[3],":",geta(yypv[1])); } break; case 88: { bundle(yypv[3],";",geta(yypv[1]),yypv[6],yypv[5],"d",yypv[3],":",geta(yypv[1])); } break; case 89: bundle(yypv[3],"Z"); break; case 90: bundle(yypv[3],"X"); break; case 91: { yyval = yypv[2]; } break; case 92:{ bundle( "?" ); } break; case 93:{ bundle( yypv[3], "v" ); } break; case 94:{ bundle("L",yypv[2]); } break; case 95: bundle(yypv[3],"dk"); break; case 96: bundle("K",yypv[3],yypv[2],"dk"); break; case 97: bundle(yypv[3],"di"); break; case 98: bundle("I",yypv[3],yypv[2],"di"); break; case 99: bundle(yypv[3],"do"); break; case 100: bundle("O",yypv[3],yypv[2],"do"); break; case 101: bundle("K"); break; case 102: bundle("I"); break; case 103: bundle("O"); break; case 105: bundle( yypv[1], yypv[3] ); break; case 107:bundle("l",geta(yypv[1])); break; case 108:{ *cp++ = '\0'; } break; case 109:{ yyval = cp; *cp++ = '_'; } break; case 110:{ yyval = cp; *cp++ = yypv[1]; } break; case 111:{ *cp++ = yypv[2]; } break; case 112:{ yyval = cp; *cp++ = crs++; *cp++ = '\0'; if(crs == '[')crs=+3; if(crs == 'a')crs='{'; if(crs == 0241){yyerror("program too big"); getout(); } bstack[bindx++] = lev++; } break; case 113:{ yyval = getf(yypv[2]); pre = ""; post = ""; lev = 1; bstack[bindx=0] = 0; } break; case 115:{ pp( yypv[1] ); } break; case 116:{ pp( yypv[3] ); } break; case 117:{ tp(yypv[1]); } break; case 118:{ tp(yypv[3]); } break; case 120:{ yyval = geta(yypv[1]); } break; } } int yyerrval 256; # define error 256 int peekc -1; int sargc; int ifile; char **sargv; extern int fin; extern int fout; char *funtab[26]{ 01,02,03,04,05,06,07,010,011,012,013,014,015,016,017, 020,021,022,023,024,025,026,027,030,031,032 }; char *atab[26]{ 0241,0242,0243,0244,0245,0246,0247,0250,0251,0252,0253, 0254,0255,0256,0257,0260,0261,0262,0263,0264,0265,0266, 0267,0270,0271,0272}; char *letr[26] { "a","b","c","d","e","f","g","h","i","j", "k","l","m","n","o","p","q","r","s","t", "u","v","w","x","y","z" } ; char *dot { "." }; yylex(){ int c,ch; restart: c = getc(); peekc = -1; while( c == ' ' || c == '\t' ) c = getc(); if( c<= 'z' && c >= 'a' ) { /* look ahead to look for reserved words */ peekc = getc(); if( peekc >= 'a' && peekc <= 'z' ){ /* must be reserved word */ if( c=='i' && peekc=='f' ){ c=_IF; goto skip; } if( c=='w' && peekc=='h' ){ c=_WHILE; goto skip; } if( c=='f' && peekc=='o' ){ c=_FOR; goto skip; } if( c=='s' && peekc=='q' ){ c=SQRT; goto skip; } if( c=='r' && peekc=='e' ){ c=_RETURN; goto skip; } if( c=='b' && peekc=='r' ){ c=_BREAK; goto skip; } if( c=='d' && peekc=='e' ){ c=_DEFINE; goto skip; } if( c=='s' && peekc=='c' ){ c= SCALE; goto skip; } if( c=='b' && peekc=='a' ){ c=BASE; goto skip; } if( c=='i' && peekc == 'b'){ c=BASE; goto skip; } if( c=='o' && peekc=='b' ){ c=OBASE; goto skip; } if( c=='d' && peekc=='i' ){ c=FFF; goto skip; } if( c=='a' && peekc=='u' ){ c=_AUTO; goto skip; } if( c == 'l' && peekc=='e'){ c=LENGTH; goto skip; } if( c == 'q' && peekc == 'u'){getout();} /* could not be found */ return( error ); skip: /* skip over rest of word */ peekc = -1; while( (ch = getc()) >= 'a' && ch <= 'z' ); peekc = ch; return( c ); } /* usual case; just one single letter */ yylval = letr[c-'a']; return( LETTER ); } if( c>= '0' && c <= '9' || c>= 'A' && c<= 'F' ){ yylval = c; return( DIGIT ); } switch( c ){ case '.': return( DOT ); case '=': switch( peekc = getc() ){ case '=': c=EQ; goto gotit; case '+': c=EQPL; goto gotit; case '-': c=EQMI; goto gotit; case '*': c=EQMUL; goto gotit; case '/': c=EQDIV; goto gotit; case '%': c=EQREM; goto gotit; case '^': c=EQEXP; goto gotit; default: return( '=' ); gotit: peekc = -1; return(c); } case '+': return( cpeek( '+', INCR, '+' ) ); case '-': return( cpeek( '-', DECR, '-' ) ); case '<': return( cpeek( '=', LE, '<' ) ); case '>': return( cpeek( '=', GE, '>' ) ); case '!': return( cpeek( '=', NE, '!' ) ); case '/': if((peekc = getc()) == '*'){ peekc = -1; while((getc() != '*') || ((peekc = getc()) != '/')); peekc = -1; goto restart; } else return(c); case '"': yylval = str; while((c=getc()) != '"'){*str++ = c; if(str >= &string[999]){yyerror("string space exceeded"); getout(); } } *str++ = '\0'; return(QSTR); default: return( c ); } } cpeek( c, yes, no ){ if( (peekc=getc()) != c ) return( no ); else { peekc = -1; return( yes ); } } getc(){ int ch; loop: ch = (peekc < 0) ? getchar() : peekc; peekc = -1; if(ch != '\0')return(ch); if(++ifile > sargc){ if(ifile >= sargc+2)getout(); fin = dup(0); ln = 0; goto loop; } close(fin); if((fin = open(sargv[ifile],0)) >= 0){ ln = 0; ss = sargv[ifile]; goto loop; } yyerror("cannot open input file"); } # define b_sp_max 3000 int b_space [ b_sp_max ]; int * b_sp_nxt { b_space }; bdebug 0; bundle(a){ int i, *p, *q; i = nargs(); q = b_sp_nxt; if( bdebug ) printf("bundle %d elements at %o\n", i, q ); for( p = &a; i-->0; ++p ){ if( b_sp_nxt >= & b_space[b_sp_max] ) yyerror( "bundling space exceeded" ); * b_sp_nxt++ = *p; } * b_sp_nxt++ = 0; yyval = q; return( q ); } routput(p) int *p; { if( bdebug ) printf("routput(%o)\n", p ); if( p >= &b_space[0] && p < &b_space[b_sp_max]){ /* part of a bundle */ while( *p != 0 ) routput( *p++ ); } else printf( p ); /* character string */ } output( p ) int *p; { routput( p ); b_sp_nxt = & b_space[0]; printf( "\n" ); flush(fout); cp = cary; crs = rcrs; } conout( p, s ) int *p; char *s; { printf("["); routput( p ); printf("]s%s\n", s ); flush(fout); lev--; } yyerror( s ) char *s; { if(ifile > sargc)ss="teletype"; printf("c[%s on line %d, %s]pc\n", s ,ln+1,ss); flush(fout); cp = cary; crs = rcrs; bindx = 0; lev = 0; b_sp_nxt = &b_space[0]; } pp( s ) char *s; { /* puts the relevant stuff on pre and post for the letter s */ bundle( "S", s, pre ); pre = yyval; bundle( post, "L", s, "s." ); post = yyval; } tp( s ) char *s; { /* same as pp, but for temps */ bundle( "0S", s, pre ); pre = yyval; bundle( post, "L", s, "s." ); post = yyval; } yyinit(argc,argv) int argc; char *argv[];{ signal( 2, &getout ); /* ignore all interrupts */ fout = dup(1); sargv=argv; sargc= -- argc; if(sargc == 0)fin=dup(0); else if((fin = open(sargv[1],0)) < 0) yyerror("cannot open input file"); ifile = 1; ln = 0; ss = sargv[1]; } getout(){ printf("q"); flush(fout); exit(); } getf(p) char *p;{ return(&funtab[*p -0141]); } geta(p) char *p;{ return(&atab[*p - 0141]); } main(argc, argv) char **argv; { int p[2]; if (argc > 1 && *argv[1] == '-') { if((argv[1][1] == 'd')||(argv[1][1] == 'c')){ yyinit(--argc, ++argv); yyparse(); exit();  } if(argv[1][1] != 'l'){ printf("unrecognizable argument\n"); flush(fout); exit(); } argv[1] = "/usr/lib/lib.b"; } pipe(p); if (fork()==0) { close(1); dup(p[1]); close(p[0]); close(p[1]); yyinit(argc, argv); yyparse(); exit(); } close(0); dup(p[0]); close(p[0]); close(p[1]); execl("/bin/dc", "dc", "-", 0); execl("/usr/bin/dc", "dc", "-", 0); } int yyact[] {0,12289,4096,16384,4352,8206,4141,8212,4354,8198 ,4355,8224,4356,8220,4357,8217,4358,8207,4359,8205 ,4361,8208,4362,8221,4366,8213,4367,8214,4368,8200 ,4369,8199,4370,8211,4371,8202,4372,8203,4373,8201 ,4381,8216,4382,8197,4219,8204,4136,8218,4222,8210 ,4159,8219,4191,8223,12295,4155,8227,4106,8226,0 ,4354,8230,12402,4139,8231,4141,8232,4138,8233,4143 ,8234,4133,8235,4190,8236,12294,12296,4157,8237,4366 ,8240,4367,8241,4374,8243,4375,8244,4376,8245,4377 ,8246,4378,8247,4379,8248,4187,8238,4136,8242,12372 ,12301,4136,8249,12304,4157,8250,4366,8252,4367,8253 ,4374,8243,4375,8244,4376,8245,4377,8246,4378,8247 ,4379,8248,4136,8254,12389,4157,8255,4366,8257,4367 ,8258,4374,8243,4375,8244,4376,8245,4377,8246,4378 ,8247,4379,8248,12390,4157,8259,4366,8261,4367,8262 ,4374,8243,4375,8244,4376,8245,4377,8246,4378,8247 ,4379,8248,12391,4352,8206,4141,8212,4354,8198,4355 ,8224,4356,8220,4357,8217,4358,8207,4359,8205,4361 ,8208,4362,8221,4366,8213,4367,8214,4368,8200,4369 ,8199,4371,8202,4372,8203,4373,8201,4381,8216,4382 ,8197,4219,8204,4136,8218,4222,8210,4159,8219,4191 ,8223,12295,12312,12313,12400,4354,8268,0,4354,8269 ,0,4141,8212,4354,8271,4355,8224,4356,8220,4357 ,8217,4366,8213,4367,8214,4371,8273,4372,8274,4373 ,8272,4381,8216,4136,8218,4222,8275,4159,8219,4191 ,8223,0,4354,8276,4371,8278,4372,8279,4373,8277 ,0,4354,8280,4371,8282,4372,8283,4373,8281,0 ,4381,8284,12367,4355,8224,4191,8223,12371,4136,8286 ,0,12380,4136,8288,0,4136,8289,0,4355,8290 ,12396,12397,12398,12290,12328,12329,4137,8291,4140,8292 ,0,12403,4187,8293,12407,12345,12348,4141,8212,4354 ,8307,4355,8224,4356,8220,4357,8217,4366,8213,4367 ,8214,4371,8273,4372,8274,4373,8272,4381,8216,4137 ,8304,4136,8218,4222,8275,4159,8219,4191,8223,0 ,12318,12319,12320,12321,12322,12323,4141,8212,4354,8271 ,4355,8224,4356,8220,4357,8217,4366,8213,4367,8214 ,4371,8273,4372,8274,4373,8272,4381,8216,4137,8309 ,4136,8218,4222,8275,4159,8219,4191,8223,0,12353 ,12355,12357,12359,12361,12363,4221,8317,4155,8227,4106 ,8226,0,12326,12325,4136,8320,0,4141,8212,4354 ,8271,4355,8224,4356,8220,4357,8217,4366,8213,4367 ,8214,4371,8273,4372,8274,4373,8272,4381,8216,4136 ,8218,4222,8275,4159,8219,4191,8223,0,4157,8323 ,12382,4136,8324,0,12339,4157,8326,4366,8240,4367 ,8241,4374,8243,4375,8244,4376,8245,4377,8246,4378 ,8247,4379,8248,4187,8325,4136,8242,12372,4157,8328 ,4366,8252,4367,8253,4374,8243,4375,8244,4376,8245 ,4377,8246,4378,8247,4379,8248,4136,8254,12389,4157 ,8330,4366,8257,4367,8258,4374,8243,4375,8244,4376 ,8245,4377,8246,4378,8247,4379,8248,12390,4157,8332 ,4366,8261,4367,8262,4374,8243,4375,8244,4376,8245 ,4377,8246,4378,8247,4379,8248,12391,4354,8334,0 ,4187,8335,12346,12354,12358,12362,4187,8336,12347,12356 ,12360,12364,4355,8224,4191,8223,12370,12368,4139,8231 ,4141,8232,4138,8233,4143,8234,4133,8235,4190,8236 ,4137,8339,0,12399,4219,8342,0,4354,8230,0 ,4189,8344,0,4138,8233,4143,8234,4133,8235,4190 ,8236,12337,4138,8233,4143,8234,4133,8235,4190,8236 ,12338,4190,8236,12340,4190,8236,12341,4190,8236,12342 ,4190,8236,12343,4139,8231,4141,8232,4138,8233,4143 ,8234,4133,8235,4190,8236,12297,4139,8231,4141,8232 ,4138,8233,4143,8234,4133,8235,4190,8236,4189,8345 ,0,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,12299,4137,8346,4140,8347,0,12366 ,12392,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,12394,4157,8326,4366,8240,4367,8241 ,4374,8243,4375,8244,4376,8245,4377,8246,4378,8247 ,4379,8248,4187,8348,4136,8242,12372,4139,8231,4141 ,8232,4138,8233,4143,8234,4133,8235,4190,8236,4137 ,8349,0,12303,4139,8231,4141,8232,4138,8233,4143 ,8234,4133,8235,4190,8236,12305,4139,8231,4141,8232 ,4138,8233,4143,8234,4133,8235,4190,8236,12306,4139 ,8231,4141,8232,4138,8233,4143,8234,4133,8235,4190 ,8236,4137,8350,0,4139,8231,4141,8232,4138,8233 ,4143,8234,4133,8235,4190,8236,12307,4139,8231,4141 ,8232,4138,8233,4143,8234,4133,8235,4190,8236,12308 ,4139,8231,4141,8232,4138,8233,4143,8234,4133,8235 ,4190,8236,12309,4139,8231,4141,8232,4138,8233,4143 ,8234,4133,8235,4190,8236,12310,12311,4352,8206,4141 ,8212,4354,8198,4355,8224,4356,8220,4357,8217,4358 ,8207,4359,8205,4361,8208,4362,8221,4366,8213,4367 ,8214,4368,8200,4369,8199,4371,8202,4372,8203,4373 ,8201,4381,8216,4382,8197,4219,8204,4136,8218,4222 ,8210,4159,8219,4191,8223,12295,4136,8352,0,4155 ,8354,0,4139,8231,4141,8232,4138,8233,4143,8234 ,4133,8235,4190,8236,4360,8355,4363,8358,4364,8360 ,4365,8359,4156,8356,4158,8357,12336,12401,12382,12369 ,4139,8231,4141,8232,4138,8233,4143,8234,4133,8235 ,4190,8236,4137,8373,0,12379,4139,8231,4141,8232 ,4138,8233,4143,8234,4133,8235,4190,8236,4137,8374 ,0,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,4155,8375,0,4155,8227,4106,8226 ,0,12404,12408,4157,8378,4366,8380,4367,8381,4374 ,8243,4375,8244,4376,8245,4377,8246,4378,8247,4379 ,8248,12344,12365,4141,8212,4354,8307,4355,8224,4356 ,8220,4357,8217,4366,8213,4367,8214,4371,8273,4372 ,8274,4373,8272,4381,8216,4136,8218,4222,8275,4159 ,8219,4191,8223,0,4141,8212,4354,8271,4355,8224 ,4356,8220,4357,8217,4366,8213,4367,8214,4371,8273 ,4372,8274,4373,8272,4381,8216,4189,8383,4136,8218 ,4222,8275,4159,8219,4191,8223,0,12302,12378,12327 ,4137,8385,0,4139,8231,4141,8232,4138,8233,4143 ,8234,4133,8235,4190,8236,12317,4139,8231,4141,8232 ,4138,8233,4143,8234,4133,8235,4190,8236,4189,8393 ,0,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,12373,4139,8231,4141,8232,4138,8233 ,4143,8234,4133,8235,4190,8236,12374,4139,8231,4141 ,8232,4138,8233,4143,8234,4133,8235,4190,8236,12383 ,4139,8231,4141,8232,4138,8233,4143,8234,4133,8235 ,4190,8236,12384,4139,8231,4141,8232,4138,8233,4143 ,8234,4133,8235,4190,8236,12385,4139,8231,4141,8232 ,4138,8233,4143,8234,4133,8235,4190,8236,12386,4139 ,8231,4141,8232,4138,8233,4143,8234,4133,8235,4190 ,8236,12387,4139,8231,4141,8232,4138,8233,4143,8234 ,4133,8235,4190,8236,12388,4139,8231,4141,8232,4138 ,8233,4143,8234,4133,8235,4190,8236,4189,8394,0 ,4139,8231,4141,8232,4138,8233,4143,8234,4133,8235 ,4190,8236,4189,8395,0,12377,12381,12324,4352,8206 ,4141,8212,4354,8198,4355,8224,4356,8220,4357,8217 ,4358,8207,4359,8205,4361,8208,4362,8221,4366,8213 ,4367,8214,4368,8200,4369,8199,4371,8202,4372,8203 ,4373,8201,4380,8397,4381,8216,4382,8197,4219,8204 ,4136,8218,4222,8210,4159,8219,4191,8223,12295,12292 ,12349,12351,12393,12395,4137,8400,0,4139,8231,4141 ,8232,4138,8233,4143,8234,4133,8235,4190,8236,4137 ,8402,0,4139,8231,4141,8232,4138,8233,4143,8234 ,4133,8235,4190,8236,12330,4139,8231,4141,8232,4138 ,8233,4143,8234,4133,8235,4190,8236,12331,4139,8231 ,4141,8232,4138,8233,4143,8234,4133,8235,4190,8236 ,12332,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,12333,4139,8231,4141,8232,4138,8233 ,4143,8234,4133,8235,4190,8236,12334,4139,8231,4141 ,8232,4138,8233,4143,8234,4133,8235,4190,8236,12335 ,4157,8403,4366,8380,4367,8381,4374,8243,4375,8244 ,4376,8245,4377,8246,4378,8247,4379,8248,12344,12350 ,12352,4221,8405,4155,8227,4106,8226,0,4354,8230 ,0,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,12298,4139,8231,4141,8232,4138,8233 ,4143,8234,4133,8235,4190,8236,12300,12291,4155,8227 ,4106,8226,4140,8414,0,12405,12314,12315,4139,8231 ,4141,8232,4138,8233,4143,8234,4133,8235,4190,8236 ,12375,4139,8231,4141,8232,4138,8233,4143,8234,4133 ,8235,4190,8236,12376,12293,12316,12406,-1}; int yypact[] {0,1,2,55,60,63,76,77,100,101 ,104,125,144,163,212,213,214,214,214,215 ,218,221,252,261,270,273,278,221,281,282 ,285,288,291,292,293,294,295,296,301,302 ,221,221,221,221,221,221,221,221,221,305 ,306,307,340,341,342,343,344,345,346,221 ,221,379,380,221,221,221,381,382,221,221 ,383,384,385,392,393,394,397,428,431,434 ,435,458,479,498,517,520,523,524,525,526 ,529,530,531,532,537,221,538,221,221,553 ,554,557,560,563,572,581,584,587,590,593 ,606,621,634,639,640,641,654,677,692,693 ,706,719,734,747,760,773,786,787,836,397 ,839,842,221,867,221,221,221,221,221,221 ,221,221,221,868,221,221,869,870,885,886 ,901,916,921,922,923,942,943,974,1007,1008 ,1009,397,1010,221,221,221,221,221,221,221 ,1013,1026,1041,1054,1067,1080,1093,1106,1119,1132 ,1145,1160,1175,1176,1177,1178,1229,221,221,1230 ,1231,1232,1233,1234,787,1237,1252,1265,1278,1291 ,1304,1317,1330,1349,1350,1351,1358,1361,1374,787 ,393,787,221,221,1387,1388,1395,1396,1397,393 ,1398,1411,1424,557,1425,1426,-1}; int yyr1[] {0,1,1,1,6,6,2,2,2,2 ,2,2,2,2,2,2,2,2,2,2 ,2,2,2,2,2,2,2,2,2,2 ,10,10,10,10,10,10,14,12,7,7 ,3,3,13,13,13,13,13,13,13,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,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,9,15,15,17,17,16,18 ,18,18,11,4,5,5,5,8,8,19 ,19,-1}; int yyr2[] {0,0,3,8,1,4,1,0,1,3 ,6,3,6,1,4,3,1,3,3,3 ,3,3,3,3,1,1,7,7,8,4 ,1,1,1,1,1,1,4,0,1,3 ,1,1,3,3,3,3,3,3,1,3 ,3,2,3,3,3,3,4,2,2,2 ,2,5,5,5,5,2,2,2,2,2 ,2,2,2,2,2,2,2,4,3,1 ,2,3,2,1,1,3,3,6,6,4 ,4,3,1,4,2,3,3,3,3,3 ,3,1,1,1,1,3,1,3,1,1 ,1,2,0,3,0,1,3,1,3,1 ,3,-1}; int yygo[] {0,-1,1,1,2,126,159,193,209,208 ,216,210,218,-1,72,2,33,150,185,214 ,221,-1,126,-1,3,-1,36,-1,184,184 ,204,-1,71,-1,214,20,78,26,95,39 ,102,40,103,41,104,42,105,43,106,44 ,107,45,108,46,109,47,110,50,114,57 ,116,58,118,59,119,62,120,63,121,64 ,122,67,123,68,124,75,130,94,146,96 ,148,97,149,128,130,131,169,133,170,134 ,171,135,172,136,173,137,174,138,175,139 ,176,140,177,141,178,143,179,144,180,155 ,114,156,170,160,130,162,194,163,195,164 ,196,165,197,166,198,167,199,168,200,186 ,206,187,207,211,219,212,220,-1,4,6 ,47,9,59,10,64,11,68,80,137,81 ,139,82,141,153,187,201,212,-1,135,16 ,74,17,75,-1,73,209,217,218,223,-1 ,127,128,161,160,192,-1,129,-1,17,-1 ,111,24,93,92,145,-1,23,155,190,-1 ,113,-1,30,100,151,205,215,222,224,-1 ,37,-1}; int yypgo[] {0,1,3,15,23,25,27,29,33,35 ,139,159,165,171,177,179,181,187,191,193 ,-1}; int nterms 53; int nnonter 19; int nstate 225; char *yysterm[] { "error", "UMINUS", "LETTER", "DIGIT", "SQRT", "LENGTH", "_IF", "FFF", "EQ", "_WHILE", "_FOR", "NE", "LE", "GE", "INCR", "DECR", "_RETURN", "_BREAK", "_DEFINE", "BASE", "OBASE", "SCALE", "EQPL", "EQMI", "EQMUL", "EQDIV", "EQREM", "EQEXP", "_AUTO", "DOT", "QSTR", 0 }; char *yysnter[] { "$accept", "start", "stat", "tail", "def", "dargs", "dlist", "slist", "dlets", "e", "EQOP", "CRS", "BLEV", "re", "fprefix", "cargs", "cons", "eora", "constant", "lora" }; 53; int nnonter 19; int nstate 225; char *yysterm[] { "error", "UMINUS", "LETTER", "DIGIT", "SQRT", "LENGTH", "_IF", "FFF", "EQ", "_WHILE", "_FOR",.globl log2 .globl getchar .globl lookchar .globl fsfile .globl seekchar .globl backspace .globl putchar .globl alterchar .globl move .globl rewind .globl create .globl zero .globl allocate .globl release .globl collect .globl w, r, a, l / cmp (sp)+,$2 blo 1f tst (sp)+ mov (sp)+,0f cmpb *0f,$'- beq 8f sys 0; 9f .data 9: sys open; 0:.=.+2; 0 .text bec 2f mov $1,r0 sys write; 4f; 5f-4f sys exit / 4: 5: .even / 2: mov r0,source 1: sys signal; 2; 1 ror r0 bcs 1f sys signal; 2; case177 1: 8: clr delflag mov $pdl,r5 / mov $10.,r0 jsr pc,log2 mov r0,log10 mov $1,r0 jsr pc,allocate mov r1,scalptr clr r0 jsr pc,putchar clr r0 jsr pc,allocate mov r1,basptr mov $10.,r0 jsr pc,putchar mov $1,r0 jsr pc,allocate mov r1,inbas mov $10.,r0 jsr pc,putchar mov $1,r0 jsr pc,allocate mov $10.,r0 jsr pc,putchar mov r1,tenptr clr r0 jsr pc,allocate mov r1,chptr clr r0 jsr pc,allocate mov r1,strptr mov $1,r0 jsr pc,allocate mov $2,r0 jsr pc,putchar mov r1,sqtemp clr r0 jsr pc,allocate mov r1,divxyz loop: tst delflag bne in177 mov sp,errstack jsr pc,readc mov $casetab,r1 1: tst (r1)+ beq 2f cmp r0,(r1)+ bne 1b jmp *-4(r1) 2: jmp eh / / / case for new line (which is special for apl box) / case012: br loop / / / case q for quit / case161: cmp readptr,$readstack+2 blos 1f mov *readptr,r1 beq 2f jsr pc,release 2: sub $2,readptr mov *readptr,r1 beq 2f jsr pc,release 2: sub $2,readptr jmp loop 1: sys exit / / / case Q for controlled quit / case121: jsr pc,pop jes eh jsr pc,length cmp r0,$2 jhi eh1 jsr pc,rewind jsr pc,getchar jmi eh1 jsr pc,release 1: cmp readptr,$readstack jlos eh mov *readptr,r1 beq 2f jsr pc,release 2: sub $2,readptr sob r0,1b jbr loop / / / case of delete character / case177: sys signal; 2; case177 mov $1,delflag mov r0,-(sp) mov 2(sp),r0 cmp -6(r0),$sys+read bne 1f sub $6,2(sp) clr delflag 1: mov (sp)+,r0 2 /rti / in177: mov $' ,ch mov $1,r0 sys write; 1f; 1 clr delflag jmp eh / .bss delflag: .=.+2 .text 1: <\n> .even / / / case digit / case060: movb r0,savec jsr pc,readin jsr pc,push br loop / / / case _ for negative numbers / case137: jsr pc,readin jsr pc,fsfile jsr pc,backspace mov r0,savk dec w(r1) jsr pc,chsign mov savk,r0 jsr pc,putchar jsr pc,push jbr loop / / / case screamer / case041: jsr pc,in041 jbr loop / in041: jsr pc,readc cmp r0,$'< jeq in74a cmp r0,$'= jeq in75a cmp r0,$'> jeq in76a / mov $field,r1 movb r0,(r1)+ 1: jsr pc,readc movb r0,(r1)+ cmpb r0,$'\n bne 1b clrb (r1)+ / sys fork br 9f sys wait mov $1,r0 sys write; screamer; 2 rts pc 9: sys exec; 6f; 8f sys exit .data 8: 6f; 7f; field; 0 6: 7: <-c\0> screamer: .even .bss field: .=.+70. .text / / / case d for duplicate / case144: cmp r5,$pdl jeq eh clr r0 jsr pc,allocate mov -2(r5),r0 jsr pc,move jsr pc,push jmp loop / / / case z for stack size / case172: clr r0 jsr pc,allocate mov r5,r3 sub $pdl,r3 asr r3 2: beq 2f clr r2 dvd $100.,r2 mov r3,r0 jsr pc,putchar mov r2,r3 br 2b 2: clr r0 jsr pc,putchar jsr pc,push jmp loop / / / case c for flush / case143: 2: jsr pc,pop jes loop jsr pc,release br 2b / / case s for save / case163: tst sfree bne 1f jsr pc,sinit 1: jsr pc,readc cmp r5,$pdl bne 2f movb $'s,ch jmp eh 2: clr r2 cmpb r0,$241 / check for array blo 1f inc r2 1: asl r0 mov stable(r0),r1 beq 2f mov r1,r0 mov 2(r0),r1 tst r2 beq 4f mov r1,-(sp) / have array - release elements jsr pc,rewind 1: mov (sp),r1 3: jsr pc,getword bes 1f tst r0 beq 3b mov r0,r1 jsr pc,release br 1b 1: mov (sp)+,r1 4: jsr pc,release jsr pc,pop mov r1,2(r0) jbr loop 2: mov sfree,stable(r0) mov stable(r0),r0 mov (r0),sfree beq symout clr (r0) jsr pc,pop mov r1,2(r0) jmp loop / symout: mov $1,r0 sys write; 7f; 8f-7f jmp reset / 7: 8: .even / / sinit: mov $sfree+4,r0 1: mov r0,-4(r0) clr -2(r0) add $4,r0 cmp r0,$sfend blos 1b clr sfend-4 rts pc / / .bss sfree: .=.+512. sfend: .text / / / case S for save / case123: tst sfree bne 1f jsr pc,sinit 1: jsr pc,readc cmp r5,$pdl bne 2f movb $'S,ch jbr eh 2: clr r3 cmp r0,$241 / check for array blo 1f inc r3 1: asl r0 mov stable(r0),r1 beq 2f mov sfree,r2 mov (r2),sfree beq symout mov stable(r0),(r2) mov r2,stable(r0) jsr pc,pop tst r3 beq 1f jsr pc,length / to make auto arrays work cmp r0,$1 bhi 1f jsr pc,zero 1: mov r1,2(r2) jbr loop 2: mov sfree,stable(r0) mov stable(r0),r2 mov (r2),sfree beq symout clr (r2) jsr pc,pop tst r3 beq 1f jsr pc,length cmp r0,$1 bhi 1f jsr pc,zero 1: mov r1,2(r2) jbr loop / / / case l for load / case154: jsr pc,in154 jmp loop / in154: jsr pc,readc clr r2 cmp r0,$241 / check for array blo 1f inc r2 1: asl r0 mov stable(r0),r1 beq 1f mov 2(r1),r1 mov r1,-(sp) jsr pc,length jsr pc,allocate tst r2 beq 2f mov r1,-(sp) / have array - copy elements mov 2(sp),r1 jsr pc,rewind 3: mov 2(sp),r1 jsr pc,getword bes 3f tst r0 beq 4f mov r0,-(sp) mov r0,r1 jsr pc,length jsr pc,allocate mov (sp)+,r0 jsr pc,move mov r1,r0 mov (sp),r1 jsr pc,putword br 3b 4: clr r0 mov (sp),r1 jsr pc,putword br 3b 3: mov (sp)+,r1 jsr pc,push tst (sp)+ rts pc 2: mov (sp)+,r0 jsr pc,move jsr pc,push rts pc 1: clr r0 jsr pc,allocate jsr pc,putword jsr pc,push rts pc / / case : for save array / case072: tst sfree bne 1f jsr pc,sinit 1: jsr pc,pop jes eh jsr pc,scalint jsr pc,fsfile jsr pc,backspace tst r0 jmi eh1 / neg. index jsr pc,length cmp r0,$2 jhi eh1 / index too high jsr pc,fsfile clr r3 cmp r0,$1 blo 1f beq 2f jsr pc,backspace mov r0,r3 mul $100.,r3 2: jsr pc,backspace add r0,r3 cmp r3,$2048. jhis eh1 / index too high asl r3 1: jsr pc,release jsr pc,readc cmp r5,$pdl bne 2f movb $':,ch jmp eh 2: asl r0 mov stable(r0),r1 beq 2f mov r1,-(sp) mov 2(r1),r1 mov l(r1),r0 sub a(r1),r0 sub $2,r0 cmp r3,r0 blos 1f mov r1,-(sp) / need more space mov r3,r0 add $2,r0 jsr pc,allocate jsr pc,zero mov (sp)+,r0 jsr pc,move mov r1,-(sp) mov r0,r1 jsr pc,release mov (sp)+,r1 1: mov r1,-(sp) mov r3,r0 jsr pc,seekchar jsr pc,getword bes 1f sub $2,r(r1) tst r0 beq 1f mov r0,r1 jsr pc,release 1: jsr pc,pop jes eh mov r1,r0 mov (sp)+,r1 jsr pc,alterchar swab r0 jsr pc,alterchar mov (sp)+,r0 mov r1,2(r0) jmp loop 2: mov sfree,stable(r0) mov stable(r0),r0 mov (r0),sfree jeq symout clr (r0) mov r0,-(sp) mov r3,r0 add $2,r0 jsr pc,allocate jsr pc,zero sub $2,r0 jsr pc,seekchar mov r1,-(sp) br 1b / / case ; for load array / case073: tst sfree bne 1f jsr pc,sinit 1: jsr pc,pop jes eh jsr pc,scalint jsr pc,fsfile jsr pc,backspace tst r0 jmi eh1 / neg. index jsr pc,length cmp r0,$2 jhi eh1 jsr pc,fsfile clr r3 cmp r0,$1 blo 1f beq 2f jsr pc,backspace mov r0,r3 mul $100.,r3 2: jsr pc,backspace add r0,r3 cmp r3,$2048. jhis eh1 / index too high asl r3 1: jsr pc,release jsr pc,readc asl r0 mov stable(r0),r1 beq 1f mov 2(r1),r1 jsr pc,length sub $2,r0 cmp r3,r0 bhi 1f / element not here mov r3,r0 jsr pc,seekchar jsr pc,getword tst r0 beq 1f mov r0,r1 mov r1,-(sp) jsr pc,length jsr pc,allocate mov (sp)+,r0 jsr pc,move jsr pc,push jmp loop 1: clr r0 jsr pc,allocate jsr pc,putword jsr pc,push jmp loop / / / case L for load / case114: jsr pc,readc clr r2 cmp r0,$241 / check for array blo 1f inc r2 1: asl r0 mov stable(r0),r1 beq 4f mov (r1),stable(r0) mov sfree,(r1) mov r1,sfree mov 2(r1),r1 tst r2 beq 2f mov r1,-(sp) / have array - assume a throw away jsr pc,rewind 1: mov (sp),r1 3: jsr pc,getword bes 1f tst r0 beq 3b mov r0,r1 jsr pc,release br 1b 1: mov (sp)+,r1 2: jsr pc,push jbr loop 4: movb $'L,ch jbr eh / / / case - for subtract / case055: jsr pc,in055 jmp loop / in055: jsr pc,pop jes eh jsr pc,fsfile jsr pc,backspace mov r0,savk dec w(r1) jsr pc,chsign mov savk,r0 jsr pc,putchar jsr pc,push br in053 / / / case + for add / case053: jsr pc,in053 jmp loop / in053: jsr pc,eqk mov $add3,r0 jsr pc,binop jsr pc,pop mov savk,r0 jsr pc,putchar jsr pc,push rts pc / / / case * for multiply / case052: jsr pc,pop jes eh mov r1,-(sp) jsr pc,pop jec 1f mov (sp)+,r1 jsr pc,push jbr eh 1: jsr pc,fsfile jsr pc,backspace mov r0,savk2 dec w(r1) mov r1,r2 mov (sp)+,r1 jsr pc,fsfile jsr pc,backspace mov r0,savk1 dec w(r1) mov r1,r3 mov $mul3,r0 jsr pc,binop jsr pc,pop cmp savk1,savk2 blo 1f mov savk1,r2 br 2f 1: mov savk2,r2 2: cmp r2,k bhis 1f mov k,r2 1: add savk2,savk1 cmp r2,savk1 bhis 1f mov r2,-(sp) neg r2 add savk1,r2 jsr pc,removc mov (sp)+,r0 2: jsr pc,putchar jsr pc,push jmp loop 1: mov savk1,r0 br 2b / / r1 = string / r2 = count / result returned in r1 (old r1 released) / removc: mov r1,-(sp) jsr pc,rewind 1: cmp r2,$1 blos 1f jsr pc,getchar sub $2,r2 br 1b 1: mov $2,r0 jsr pc,allocate mov r1,-(sp) 1: mov 2(sp),r1 jsr pc,getchar bes 1f mov (sp),r1 jsr pc,putchar mov r1,(sp) br 1b 1: cmp r2,$1 bne 1f mov (sp),r3 mov tenptr,r2 jsr pc,div3 mov r1,(sp) mov r3,r1 jsr pc,release  mov r4,r1 jsr pc,release 1: mov 2(sp),r1 jsr pc,release mov (sp)+,r1 tst (sp)+ rts pc / / case / for divide / case057: jsr pc,dscale mov $div3,r0 jsr pc,binop mov r4,r1 jsr pc,release tst rem beq 1f mov rem,r1 jsr pc,release 1: jsr pc,pop mov k,r0 jsr pc,putchar jsr pc,push jmp loop / / dscale: jsr pc,pop jes eh mov r1,-(sp) jsr pc,pop bec 1f mov (sp)+,r1 jsr pc,push jmp eh 1: mov r1,-(sp) jsr pc,fsfile jsr pc,backspace mov r0,savk1 dec w(r1) jsr pc,rewind mov 2(sp),r1 jsr pc,fsfile jsr pc,backspace mov r0,savk2 1: jsr pc,backspace bes 3f tst r0 beq 1b dec w(r1) mov k,r2 sub savk1,r2 add savk2,r2 mov (sp)+,r1 tst r2 bmi 1f jsr pc,add0 clr rem br 2f 1: neg r2 jsr pc,removr 2: mov r1,r3 mov (sp)+,r2 rts pc 3: mov (sp)+,r1 jsr pc,release mov (sp)+,r1 jmp eh1 removr: mov r1,-(sp) jsr pc,rewind mov r2,r0 inc r0 asr r0 jsr pc,allocate mov r1,-(sp) 1: cmp r2,$1 blos 1f mov 2(sp),r1 jsr pc,getchar mov (sp),r1 jsr pc,putchar sub $2,r2 br 1b 1: mov $2,r0 jsr pc,allocate mov r1,-(sp) 1: mov 4(sp),r1 jsr pc,getchar bes 1f mov (sp),r1 jsr pc,putchar mov r1,(sp) br 1b 1: cmp r2,$1 bne 2f mov (sp),r3 mov tenptr,r2 jsr pc,div3 mov r1,(sp) mov r3,r1 jsr pc,release mov r4,r1 jsr pc,getchar beq 1f mov 2(sp),r1 jsr pc,putchar 1: mov r4,r1 jsr pc,release 2: mov 4(sp),r1 jsr pc,release mov (sp)+,r1 mov (sp)+,rem tst (sp)+ rts pc .bss rem: .=.+2 .text / / / case % for remaindering / case045: jsr pc,dscale mov $div3,r0 jsr pc,binop jsr pc,pop jsr pc,release mov r4,r1 mov savk2,r0 add k,r0 tst rem bne 1f jsr pc,putchar jsr pc,push jmp loop 1: mov savk1,r2 sub r0,r2 jsr pc,add0 mov r1,r2 mov rem,r3 jsr pc,add3 mov r1,-(sp) mov r2,r1 jsr pc,release mov r3,r1 jsr pc,release mov (sp)+,r1 mov savk1,r0 jsr pc,putchar jsr pc,push jmp loop / / binop: jsr pc,(r0) jsr pc,push mov r2,r1 jsr pc,release mov r3,r1 jsr pc,release rts pc / eqk: jsr pc,pop jes eh mov r1,-(sp) jsr pc,pop bec 1f mov (sp)+,r1 jsr pc,push jbr eh 1: mov r1,-(sp) mov 2(sp),r1 jsr pc,fsfile jsr pc,backspace mov r0,savk1 dec w(r1) mov (sp),r1 jsr pc,fsfile jsr pc,backspace mov r0,savk2 dec w(r1) cmp r0,savk1 beq 1f blo 2f mov savk2,savk mov r0,r2 sub savk1,r2 mov 2(sp),r1 jsr pc,add0 mov r1,2(sp) br 4f 2: mov savk1,r2 sub savk2,r2 mov (sp),r1 jsr pc,add0 mov r1,(sp) 1: mov savk1,savk 4: mov 2(sp),r3 mov (sp)+,r2 tst (sp)+ rts pc .bss savk1: .=.+2 savk2: .=.+2 savk: .=.+2 .text / / / r2 = count / r1 = ptr / returns ptr in r1 add0: mov r1,-(sp) jsr pc,length jsr pc,allocate clr r0 1: cmp r2,$1 blos 1f jsr pc,putchar sub $2,r2 br 1b 1: mov r1,-(sp) mov 2(sp),r1 jsr pc,rewind 1: jsr pc,getchar bes 1f mov (sp),r1 jsr pc,putchar mov r1,(sp) mov 2(sp),r1 br 1b 1: cmp r2,$1 bne 1f mov (sp),r3 mov tenptr,r2 jsr pc,mul3 mov r1,(sp) mov r3,r1 jsr pc,release 1: mov 2(sp),r1 jsr pc,release mov (sp)+,r1 tst (sp)+ rts pc / case i for input base / case151: jsr pc,in151 jmp loop / in151: jsr pc,pop jes eh jsr pc,scalint mov r1,-(sp) mov inbas,r1 mov (sp)+,inbas jsr pc,release rts pc case111: mov inbas,r1 jsr pc,length inc r0 jsr pc,allocate mov inbas,r0 jsr pc,move clr r0 jsr pc,putchar /scale jsr pc,push jmp loop / .bss inbas: .=.+2 .data / / / case o for output base / case157: jsr pc,in157 jmp loop / in157: jsr pc,pop jes eh jsr pc,scalint mov r1,-(sp) jsr pc,length jsr pc,allocate mov (sp),r0 jsr pc,move jsr pc,fsfile jsr pc,length 1: cmp r0,$1 beq 1f  jsr pc,backspace bpl 2f jsr pc,chsign jsr pc,length br 1b 2: clr sav mov r0,-(sp) 2: jsr pc,backspace bes 2f mov (sp),r2 clr r3 mul $100.,r2 add r0,r3 mov r3,(sp) tst sav beq 3f mov r2,r0 clr r3 mov sav,r2 mul $100.,r2 mov r3,sav add r0,sav br 2b 3: mov r2,sav br 2b 2: mov (sp)+,r0 tst sav beq 2f mov sav,r0 jsr pc,log2 add $16.,r0 mov r0,logo br 3f 1: jsr pc,backspace 2: tst r0 bpl 1f mov $15.,logo br 3f 1: jsr pc,log2 mov r0,logo 3: jsr pc,release mov basptr,r1 jsr pc,release mov (sp),basptr / / set field widths for output / and set output digit handling routines / mov (sp),r1 mov $bigout,outdit jsr pc,length cmp r0,$1. bne 2f jsr pc,fsfile jsr pc,backspace cmp r0,$16. bhi 2f mov $hexout,outdit 2: jsr pc,length jsr pc,allocate mov (sp),r0 jsr pc,move clr (sp) jsr pc,fsfile jsr pc,backspace bpl 2f add $1.,(sp) jsr pc,chsign 2: mov r1,r2 mov $1,r0 jsr pc,allocate mov $-1,r0 jsr pc,putchar mov r1,r3 jsr pc,add3 jsr pc,length asl r0 add r0,(sp) jsr pc,fsfile jsr pc,backspace cmp r0,$9. blos 2f add $1,(sp) 2: jsr pc,release mov r2,r1 jsr pc,release mov r3,r1 jsr pc,release mov (sp)+,fw mov fw,fw1 dec fw1 cmp outdit,$hexout bne 2f mov $1,fw clr fw1 2: mov $70.,ll cmp fw,$70. blo 9f; rts pc; 9: mov $70.,r1 clr r0 dvd fw,r0 mov r0,r1 mpy fw,r1 mov r1,ll rts pc case117: mov basptr,r1 jsr pc,length inc r0 jsr pc,allocate mov basptr,r0 jsr pc,move clr r0 jsr pc,putchar /scale jsr pc,push jmp loop / .data fw: 1  /field width for digits fw1: 0 ll: 70. /line length .text / / / case k for skale factor / case153: jsr pc,pop jes eh jsr pc,scalint mov w(r1),r0 sub a(r1),r0 cmp r0,$1 jhi eh1 jsr pc,rewind jsr pc,getchar jmi eh1 mov r0,k mov r1,-(sp) mov scalptr,r1 jsr pc,release mov (sp)+,scalptr jmp loop / case113: mov scalptr,r1 jsr pc,length inc r0 jsr pc,allocate mov scalptr,r0 jsr pc,move clr r0 jsr pc,putchar jsr pc,push jmp loop scalint: jsr pc,fsfile jsr pc,backspace dec w(r1) mov r0,r2 jsr pc,removc rts pc / / scale of top of stack / case130: jsr pc,pop jsr pc,fsfile jsr pc,backspace jsr pc,release mov r0,-(sp) mov $1,r0 jsr pc,allocate mov (sp)+,r0 jsr pc,putchar clr r0 jsr pc,putchar jsr pc,push jmp loop / / length of top of stack / case132: jsr pc,pop mov w(r1),r0 sub a(r1),r0 dec r0 asl r0 mov r0,-(sp) /length jsr pc,fsfile jsr pc,backspace /scale jsr pc,backspace bes 2f cmp r0,$-1 bne 1f sub $2,(sp) jsr pc,backspace bes 3f beq 3f cmp r0,$90. ble 2f dec (sp) br 2f 3: inc (sp) br 2f 1: cmp r0,$10. bhis 2f dec (sp) 2: mov $1,r0 jsr pc,allocate mov (sp)+,r3 tst r3 ble 2f 2: cmp r3,$100. blo 2f clr r2 div $100.,r2 mov r3,r0 jsr pc,putchar mov r2,r3 br 2b 2: mov r3,r0 jsr pc,putchar clr r0 jsr pc,putchar jsr pc,push jmp loop / / case ^ for exponentiation / case136: jsr pc,pop jes eh jsr pc,fsfile jsr pc,backspace jne eh dec w(r1) jsr pc,fsfile jsr pc,backspace tst r0 bge 1f inc negexp jsr pc,chsign 1: jsr pc,length cmp r0,$3 jhis eh1 mov r1,r3 jsr pc,pop jes eh jsr pc,fsfile jsr pc,backspace mov r0,savk dec w(r1) mov r1,r2 jsr pc,exp3 mov r1,-(sp) mov r2,r1 jsr pc,release mov r3,r1 jsr pc,rewind jsr pc,getchar mov r0,-(sp) jsr pc,getchar bes 2f mov r0,r1 mul $100.,r1 add (sp)+,r1 br 3f 2: mov (sp)+,r1 3: mul savk,r1 mov r1,r2 mov r3,r1 jsr pc,release tst negexp bne 4f cmp k,savk blo 1f mov k,r3 br 2f 1: mov savk,r3 2: cmp r3,r2 bhis 4f sub r3,r2 mov (sp)+,r1 mov r3,-(sp) jsr pc,removc mov (sp)+,r0 jsr pc,putchar jsr pc,push br 3f 4: mov (sp)+,r1 mov r2,r0 jsr pc,putchar jsr pc,push 3: tst negexp jeq loop clr negexp jsr pc,pop mov r1,-(sp) mov $2,r0 jsr pc,allocate mov $1,r0 jsr pc,putchar clr r0 jsr pc,putchar jsr pc,push mov (sp)+,r1 jsr pc,push jmp case057 / .bss sav: .=.+2 negexp: .=.+2 .text / / case v for square root / case166: jsr pc,pop jes eh / jsr pc,fsfile jsr pc,backspace mov r0,savk dec w(r1) mov w(r1),r2 sub a(r1),r2 tst r2 beq sqz  jsr pc,backspace tst r0 jmi eh1 cmp k,savk blo 1f mov k,r2 asl r2 sub savk,r2 mov k,savk br 2f 1: mov savk,r2 2: jsr pc,add0 jsr pc,sqrt mov savk,r0 jsr pc,putchar jsr pc,push jmp loop / / sqz: mov savk,r0 jsr pc,putchar jsr pc,push jmp loop .bss sqtemp: .=.+2 .text / / / case [ for subroutine definition / case133: clr -(sp) clr r0 jsr pc,allocate jsr pc,push 1: jsr pc,readc cmp r0,$'] bne 3f tst (sp) beq 1f dec (sp) br 2f 3: cmp r0,$'[ bne 2f inc (sp) 2: jsr pc,putchar br 1b / 1: tst (sp)+ jmp loop / / / case x for execute top of stack / case170: jsr pc,in170 jmp loop / in170: jsr pc,pop jes eh mov r1,-(sp) tst *readptr beq 1f mov *readptr,r1 cmp r(r1),w(r1) bne 1f jsr pc,release br 2f 1: add $2,readptr cmp readptr,$readtop bhis 1f 2: mov (sp)+,r1 mov r1,*readptr beq 2f jsr pc,rewind rts pc 2: jsr pc,readc cmp r0,$'\n beq 3f mov r0,savec 3: rts pc 1: nderr: mov $1,r0 sys write; 1f; 2f-1f jmp reset 1: 2: .even / .data readptr: readstack .bss readstack: .=.+100. readtop: .text / / case ? for apl box function / case077: add $2,readptr cmp readptr,$readtop bhis nderr clr *readptr in077: mov source,-(sp) clr source jsr pc,readc cmp r0,$'! bne 1f jsr pc,in041 mov (sp)+,source br in077 1: mov r0,savec clr r0 jsr pc,allocate 2: jsr pc,readc jsr pc,putchar 1: jsr pc,readc jsr pc,putchar cmp r0,$'\\ beq 2b cmp r0,$'\n bne 1b mov (sp)+,source mov r1,*readptr jmp loop / / / case < for conditional execution / case074: jsr pc,in074 ble neg074 jmp aff074 / / / case !< for conditional execution / in74a: jsr pc,in074 bgt inneg jmp inaff / in074: jsr pc,in055 /go subtract jsr pc,pop jsr pc,length tst r0 beq 1f jsr pc,fsfile jsr pc,backspace jsr pc,backspace tst r0 1: rts pc / aff074: jsr pc,release jsr pc,in154 /load from register jmp case170 / neg074: jsr pc,release jsr pc,readc jmp loop / / / case = for conditional execution / case075: jsr pc,in074 beq aff074 jmp neg074 / / / case != for conditional execution / in75a: jsr pc,in074 bne inaff jmp inneg / / / case > for conditional execution / case076: jsr pc,in074 bge neg074 jmp aff074 / / / case !> for conditional execution / in76a: jsr pc,in074 blt inneg jmp inaff / inaff: jsr pc,release jsr pc,in154 jsr pc,in170 rts pc / inneg: jsr pc,release jsr pc,readc rts pc / err: mov $1,r0 sys write; 1f; 2f-1f jmp reset 1: ; 2: .even / eh1: jsr pc,release eh: movb ch,1f+2 mov $1,r0 sys write; 1f; 2f-1f mov $readstack,readptr mov errstack,sp jmp loop .data 1: <( ) ?\n> 2: .even .text / / / routine to read and convert a number from the / input stream. Numbers beginnig with 0 are / converted as octal. Routine converts / up to next nonnumeric. / / readin: clr dp clr dpt clr r0 jsr pc,allocate mov r1,-(sp) mov strptr,r1 jsr pc,create jsr pc,readc 1: cmpb ch,$'0 blt 3f cmpb ch,$'9 bgt 3f mov ch,r0 sub $'0,r0 4: tst dp beq 8f cmp dpt,$99. beq 5f inc dpt 8: mov chptr,r1 jsr pc,create tst r0 beq 2f jsr pc,putchar 2: mov r1,chptr mov (sp),r3 mov inbas,r2 jsr pc,mul3 mov r1,(sp) mov r3,r1 jsr pc,release mov (sp),r3 mov chptr,r2 jsr pc,add3 mov r1,(sp) mov r3,r1 jsr pc,release 5: jsr pc,readc mov r0,ch br 1b 3: cmpb ch,$'A blt 1f cmpb ch,$'F bgt 1f mov ch,r0 sub $67,r0 br 4b 1: cmpb ch,$134 /backslash bne 1f jsr pc,readc br 5b 1: cmpb ch,$'. bne 1f tst dp bne 1f inc dp clr dpt br 5b 1: mov r0,savec / / scale up or down 2: tst dp bne 1f mov (sp)+,r1 clr r0 jsr pc,putchar rts pc 1: mov (sp),r1 jsr pc,scale mov dpt,r0 jsr pc,putchar tst (sp)+ rts pc / .bss dp: .=.+2 dpt: .=.+2 .text / scale: mov dpt,r2 jsr pc,add0 mov r1,-(sp) mov $1,r0 jsr pc,allocate mov dpt,r0 jsr pc,putchar mov r1,r3 mov inbas,r2 jsr pc,exp3 mov r1,-(sp) mov r3,r1 jsr pc,release mov (sp)+,r2 mov (sp)+,r3 jsr pc,div3 mov r1,-(sp) mov r2,r1 jsr pc,release mov r3,r1 jsr pc,release mov r4,r1 jsr pc,release mov (sp)+,r1 rts pc / / routine to read another character from the input / stream. If the caller does not want the character, / it is to be placed in the cell savec. / The routine exits to the system on end of file. / Character is returned in r0. / / jsr pc,readc / movb r0,... / / readc: tst savec beq 1f movb savec,r0 bic $177400,r0 clr savec rts pc 1: tst *readptr bne 1f 2: mov source,r0 sys read; ch; 1 bes eof tst r0 beq eof movb ch,r0 bic $177400,r0 rts pc 1: mov r1,-(sp) mov *readptr,r1 jsr pc,getchar bes eof1 bic $177400,r0 mov r0,ch mov (sp)+,r1  rts pc / eof: tst source beq 1f clr source br 2b 1: sys exit / eof1: mov *readptr,r1 beq 2f jsr pc,release 2: sub $2,readptr mov (sp)+,r1 jmp readc / / / case p for print / case160: cmp r5,$pdl jeq eh jsr pc,in160 jmp loop / / in160: / mov $1,r0 / sys write; sphdr; 4 br 1f / sphdr: < > .even / 1: cmp r5,$pdl bne 1f mov $1,r0 sys write; qm; 1 mov $1,r0 sys write; nl; 1 rts pc / / do the conversion / 1: mov -2(r5),r1 jsr pc,printf rts pc / / / case f for print the stack / case146: mov r5,-(sp) 1: cmp r5,$pdl beq 2f 1: jsr pc,in160 jsr pc,pop cmp r5,$pdl bne 1b 2: mov $stable-2,r2 1: tst (r2)+ cmp r2,$stable+254. bhi 1f / mov (r2),r3 beq 1b movb $'0,7f+3 mov r2,r0 sub $stable,r0 asr r0 movb r0,7f+1 3: mov $1,r0 sys write; 7f; 8f-7f .data 7: <" (0)"> 8: .even .text mov 2(r3),r1 jsr pc,printf tst (r3) beq 1b incb 7b+3 mov (r3),r3 br 3b 1: mov (sp)+,r5 jbr loop / / / routine to convert to decimal and print the / top element of the stack. / / jsr pc,printf / / printf: mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) clr -(sp) jsr pc,rewind 2: jsr pc,getchar bes 2f cmp r0,$143 blos 2b cmp r0,$-1 beq 2b bis $1,(sp) br 2b 2: tst (sp)+ beq 2f jsr pc,length mov r0,0f mov a(r1),3f mov $1,r0 sys 0; 9f .data 9: sys write; 3:.=.+2; 0:.=.+2 .text jbr prout 2: jsr pc,fsfile jsr pc,backspace bec 1f mov $1,r0 sys write; asczero; 1 jbr prout 1: jsr pc,length mov r1,-(sp) jsr pc,allocate mov (sp),r0 mov r1,(sp) jsr pc,move  mov ll,count / inc count jsr pc,fsfile jsr pc,backspace mov r0,savk dec w(r1) jsr pc,backspace cmpb r0,$-1 bne 2f mov basptr,r1 jsr pc,fsfile jsr pc,backspace cmp r0,$-1 beq 2f mov (sp),r1 jsr pc,chsign mov $'-,ch jsr pc,wrchar br 1f 2: / mov $' ,ch / jsr pc,wrchar 1: mov strptr,r1 jsr pc,create mov basptr,r1 jsr pc,length cmp r0,$1 jlo dingout bne 1f jsr pc,rewind jsr pc,getchar cmp r0,$1. jeq unout cmp r0,$-1 jeq dingout cmp r0,$10. jeq tenout 1: mov log10,r1 mul savk,r1 mov r1,r2 clr r0 div $10.,r0 mov r0,r1 add r2,r1 /log10 should be 3.3 clr r0 div logo,r0 mov r0,dout clr ct 1: mov (sp),r3 mov savk,r2 jsr pc,getdec mov r1,decimal clr dflg mov (sp),r1 mov savk,r2 jsr pc,removc mov r1,(sp) 1: mov (sp),r3 mov basptr,r2 jsr pc,div3 mov r1,r2 mov (sp),r1 jsr pc,release mov r2,(sp) mov r4,r1 jsr pc,*outdit mov (sp),r1 jsr pc,length bne 1b / mov strptr,r1 jsr pc,fsfile 1: jsr pc,backspace bes 1f mov r0,ch jsr pc,wrchar br 1b 1: mov (sp)+,r1 jsr pc,release tst savk bne 1f mov decimal,r1 jsr pc,release br prout 1: mov dot,ch jsr pc,wrchar mov strptr,r1 jsr pc,create mov decimal,-(sp) inc dflg 1: mov (sp),r3 mov basptr,r2 jsr pc,mul3 mov r1,(sp) mov r3,r1 jsr pc,release mov (sp),r3 mov savk,r2 jsr pc,getdec mov r1,(sp) mov r3,r1 mov savk,r2 jsr pc,removc jsr pc,*outdit mov strptr,r1 inc ct cmp ct,dout blo 1b mov (sp)+,r1 jsr pc,release mov strptr,r1 jsr pc,rewind 1: jsr pc,getchar bes 1f mov r0,ch jsr pc,wrchar br 1b 1: / / cleanup, print new line and return / prout: mov $1,r0 sys write; nl; 1 mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 rts pc / / / / r2 = count / r3 = pointer (not released) / .bss dflg: .=.+2 dout: .=.+2 logo: .=.+2 log10: .=.+2 decimal: .=.+2 .text getdec: mov r3,-(sp) mov r3,r1 jsr pc,rewind jsr pc,length jsr pc,allocate mov r1,-(sp) 1: cmp r2,$1 blt 1f mov 2(sp),r1 jsr pc,getchar mov (sp),r1 jsr pc,putchar mov r1,(sp) sub $2,r2 br 1b 1: tst r2 beq 1f mov tenptr,r2 mov (sp),r3 jsr pc,mul3 mov r1,(sp) mov r3,r1 jsr pc,length jsr pc,release mov r0,r3 jsr pc,allocate mov r1,-(sp) mov 2(sp),r1 jsr pc,rewind 2: tst r3 beq 2f jsr pc,getchar mov (sp),r1 jsr pc,putchar mov r1,(sp) dec r3 mov 2(sp),r1 br 2b 2: clr r0 mov (sp),r1 jsr pc,putchar mov 2(sp),r1 jsr pc,release mov (sp),r3 mov tenptr,r2 jsr pc,div3 mov r1,(sp) mov r3,r1 jsr pc,release mov r4,r1 jsr pc,release mov (sp)+,r1 tst (sp)+ mov (sp)+,r3 rts pc 1: mov (sp)+,r1 mov (sp)+,r3 rts pc tenout: mov savk,ct mov $2,r0 jsr pc,allocate mov r1,-(sp) mov 2(sp),r1 jsr pc,fsfile jsr pc,backspace mov r0,r3 clr r2 dvd $10.,r2 beq 1f 3: add $60,r2 mov r2,r0 mov (sp),r1 jsr pc,putchar mov r1,(sp) 1: mov (sp),r1 add $60,r3 mov r3,r0 jsr pc,putchar mov 2(sp),r1 1: jsr pc,backspace bec 2f mov (sp),r1 jsr pc,length cmp r0,ct beq 4f blo 5f sub ct,r0 mov r0,ct 1: jsr pc,getchar mov r0,ch jsr pc,wrchar dec ct bne 1b jsr pc,getchar bes 6f jsr pc,backspace 4: movb dot,ch jsr pc,wrchar 1: jsr pc,getchar bes 1f mov r0,ch jsr pc,wrchar br 1b 5: sub r0,ct movb dot,ch jsr pc,wrchar mov $60,ch 5: jsr pc,wrchar dec ct bne 5b br 1b 1: 6: mov (sp)+,r1 jsr pc,release mov (sp)+,r1 jsr pc,release jbr prout 2: mov r0,r3 clr r2 dvd $10.,r2 br 3b dot: <.> .even ct: .=.+2 / / dingout: clr -(sp) br 1f unout: mov $1,-(sp) 1: mov 2(sp),r1 mov savk,r2 jsr pc,removc mov r1,2(sp) mov strptr,r1 jsr pc,create mov $-1,r0 jsr pc,putchar mov r1,r3 1: mov 2(sp),r1 jsr pc,length beq 1f mov r1,r2 jsr pc,add3 mov r1,2(sp) mov r2,r1 jsr pc,release mov $1,r0 tst (sp) beq 2f mov $'1,ch jsr pc,wrchar br 1b 2: tst delflag jne in177 sys write; ding; 3 br 1b 1: tst (sp)+ mov (sp)+,r1 jsr pc,release jmp prout / ding: < > / sp5: <\\\n > minus: <-> one: <1> .even .bss count: .=.+2 .text / bigout: mov r1,-(sp) /big digit tst dflg beq 1f clr r0 jsr pc,allocate mov r1,tptr 1: mov strptr,r1 jsr pc,length add fw,r0 dec r0 mov r0,-(sp) /end of field clr -(sp) /negative mov 4(sp),r1 jsr pc,length bne 2f mov $'0,r0 tst dflg beq 3f mov tptr,r1 jsr pc,putchar mov r1,tptr br 1f 3: mov strptr,r1 jsr pc,putchar br 1f 2: mov 4(sp),r1 /digit jsr pc,fsfile jsr pc,backspace bpl 2f mov $1,(sp) /negative jsr pc,chsign 2: mov 4(sp),r3 /digit mov r3,r1 jsr pc,length beq 1f mov tenptr,r2 jsr pc,div3 mov r1,4(sp) /digit mov r3,r1 jsr pc,release mov r4,r1 jsr pc,rewind jsr pc,getchar jsr pc,release add $'0,r0 tst dflg beq 3f mov tptr,r1 jsr pc,putchar mov r1,tptr br 2b 3: mov strptr,r1 jsr pc,putchar br 2b 1: tst dflg beq 4f mov tptr,r1 jsr pc,length cmp r0,fw1 bhis 2f mov fw1,r1 sub r0,r1 mov r1,-(sp) mov strptr,r1 3: mov $'0,r0 jsr pc,putchar dec (sp) bne 3b tst (sp)+ 2: mov tptr,r1 jsr pc,fsfile 2: mov tptr,r1 jsr pc,backspace bes 2f mov strptr,r1 jsr pc,putchar br 2b 2: mov tptr,r1 jsr pc,release br 1f 4: mov strptr,r1 jsr pc,length cmp r0,2(sp) /end of field bhis 1f mov $'0,r0 jsr pc,putchar br 1b 1: tst (sp) /negative beq 1f mov $'-,r0 mov strptr,r1 dec w(r1) jsr pc,putchar 1: mov strptr,r1 mov $' ,r0 jsr pc,putchar tst (sp)+ tst (sp)+ mov (sp)+,r1 jsr pc,release rts pc / .bss tptr: .=.+2 tenptr: .=.+2 .text / / / hexout: mov r1,-(sp) jsr pc,rewind jsr pc,getchar cmp r0,$16. blo 1f jmp err 1: add $60,r0 cmp r0,$'9 blos 2f add $'A-'9-1,r0 2: mov strptr,r1 jsr pc,putchar mov (sp)+,r1 jsr pc,release rts pc / / wrchar: tst delflag jne in177 mov $1,r0 tst count bne 7f sys write; sp5; 2 mov ll,count mov $1,r0 7: dec count sys write; ch; 1 rts pc / / / case P for print an ascii string / / case120: jsr pc,pop jes eh jsr pc,length mov r0,0f mov a(r1),3f mov $1,r0 sys 0; 9f jsr pc,release jmp loop .data 9: sys write; 3:.=.+2; 0:.=.+2 .text / / / here for unimplemented stuff / junk: movb r0,1f mov $1,r0 sys write; 1f; 2f-1f jmp loop .data 1: <0 not in switch.\n> 2: .even .text / / / / routine to place one word onto the pushdown list / Error exit to system on overflow. / / push: mov r1,(r5)+ cmp r5,$pdltop bhis pdlout rts pc / pdlout: mov $1,r0 sys write; 1f; 2f-1f jmp reset 1: 2: .even / / / routine to remove one word from the pushdown list / carry bit set on empty stack / / / jsr pc,pop / pop: cmp r5,$pdl bhi 1f clr r1 sec rts pc 1: mov -(r5),r1 clc rts pc / / / / .data outdit: hexout .bss source: .=.+2 savec: .=.+2 ch: .=.+2 .text nl: <\n> asczero: <0> qm: <?\n> .even / .bss chptr: .=.+2 strptr: .=.+2 basptr: .=.+2 scalptr: .=.+2 errstack:.=.+2 / stable: .=.+512. .text casetab: case012; 012 /nl loop; 040 /sp case041; 041 /! case045; 045 /% case052; 052 /* case053; 053 /+ case055; 055 /- case060; 056 /. case057; 057 // case060; 060 /0 case060; 061 /1 case060; 062 /2 case060; 063 /3 case060; 064 /4 case060; 065 /5 case060; 066 /6 case060; 067 /7 case060; 070 /8 case060; 071 /9 case072; 072 /: case073; 073 /; case074; 074 /< case075; 075 /= case076; 076 /> case077; 077 /? case060; 101 /A case060; 102 /B case060; 103 /C case060; 104 /D case060; 105 /E case060; 106 /F case111; 111 /I case113; 113 /K case114; 114 /L case117; 117 /O case120; 120 /P case121; 121 /Q case123; 123 /S case166; 126 /V case130; 130 /X scale of top of stack case132; 132 /Z length of top of stack case133; 133 /[ case136; 136 /^ case137; 137 /_ case143; 143 /c case144; 144 /d case146; 146 /f case151; 151 /i case153; 153 /k case154; 154 /l case157; 157 /o case160; 160 /p case161; 161 /q case163; 163 /s case166; 166 /v case170; 170 /x case172; 172 /z 0;0 / .bss pdl: .=.+100. pdltop: .text reset: clr r0 sys seek; 0; 2 1: clr r0 sys read; rathole; 1 bes 1f tst r0 beq 1f cmpb rathole,$'q bne 1b 1: sys exit .bss rathole: .=.+2 .text stack case132; 132 /Z length of top of stack case133; 133 /[ case136; 136 /^ case137; 137 /_ case143; 143 /c case144; 144 /d case146; 146 /f case151; 151 /i case153; 153 /k case154; 154 /l c/ / / routine to add the two centennial numbers / pointed to by r2 and r3. / a pointer to the result is returned in r1 / r2 and r3 are preserved / / mov ptr1,r2 / mov ptr2,r3 / jsr pc,add3 / mov r1,... / add3: mov r0,-(sp) mov r4,-(sp) mov r5,-(sp) mov r3,-(sp) mov r2,-(sp) / / allocate a new string whose length is / the max of the two addends. / mov w(r2),r0 sub a(r2),r0 mov w(r3),r4 sub a(r3),r4 cmp r0,r4 bgt 1f mov r4,r0 1: mov r0,r4 jsr pc,allocate mov r1,-(sp) / / get everything ready / mov 2(sp),r1 jsr pc,rewind mov 4(sp),r1 jsr pc,rewind clr carry / / now add them / 2: dec r4 blt 3f mov 2(sp),r1 /r2 jsr pc,getchar mov r0,r5 mov 4(sp),r1 /r3 jsr pc,getchar add r5,r0 add carry,r0 clr carry cmp r0,$100. blt 1f sub $100.,r0 mov $1,carry 1: tstb r0 bpl 1f add $100.,r0 mov $-1,carry 1: mov (sp),r1 /r1 jsr pc,putchar br 2b / / perhaps there is an extra digit / 3: mov carry,r0 beq 2f mov (sp),r1 /r1 jsr pc,putchar / / strip leading zeros / 2: jsr pc,fsfile 2: jsr pc,backspace bes 2f beq 2b inc r(r1) 2: mov r(r1),w(r1) / / strip leading 99's / jsr pc,fsfile jsr pc,backspace cmpb r0,$-1 bne 1f 2: jsr pc,backspace bes 2f cmpb r0,$99. beq 2b jsr pc,getchar 2: mov $-1,r0 jsr pc,alterchar mov r(r1),w(r1) / / restore and return / 1: mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r0 rts pc / .bss carry: .=.+2 .text / / / routine to change the sign of the centennial number / pointed to by r1. / negative numbers are stored in 100's complement form with / -1 as the high order digit; the second digit is not 99. / / mov ...,r1 / jsr pc,chsign / chsign: mov r1,-(sp) mov r0,-(sp) jsr pc,rewind clr chcarry / 1: jsr pc,lookchar bes 1f negb r0 sub chcarry,r0 mov $1,chcarry add $100.,r0 cmpb $100.,r0 bgt 2f sub $100.,r0 clr chcarry 2: jsr pc,alterchar br 1b / 1: clr r0 sub chcarry,r0 beq 2f jsr pc,putchar jsr pc,fsfile jsr pc,backspace jsr pc,backspace cmp r0,$99. bne 1f mov r(r1),w(r1) mov $-1,r0 jsr pc,putchar br 1f / 2: jsr pc,fsfile jsr pc,backspace bne 1f mov r(r1),w(r1) / 1: mov (sp)+,r0 mov (sp)+,r1 rts pc / .bss chcarry: .=.+2 .text / / / / / routine to multiply the two centennial numbers / pointed to by r2 and r3. / a pointer to the result is returned in r1 / r2 and r3 are preserved / / mov ptr1,r2 / mov ptr2,r3 / jsr pc,mul3 / mov r1,... / / save registers and make space for temps / mul3: mov r5,-(sp) mov r3,-(sp) /arg2 mov r2,-(sp) /arg1 mov r0,-(sp) tst -(sp) /result tst -(sp) /arg1 tst -(sp) /arg2 tst -(sp) /carry / / compute sign of result and make args positive / clr outsign mov r2,r1 jsr pc,fsfile jsr pc,backspace bmi 2f mov r2,4(sp) /arg1 br 1f 2: jsr pc,length jsr pc,allocate mov r1,4(sp) mov r2,r0 jsr pc,move jsr pc,chsign com outsign 1: mov r3,r1 jsr pc,fsfile jsr pc,backspace bmi 2f mov r3,2(sp) /arg2 br 1f 2: mov r3,r1 jsr pc,length jsr pc,allocate mov r1,2(sp) mov r3,r0 jsr pc,move jsr pc,chsign com outsign 1: / / compute the length of the result and / allocate space for it / mov w(r2),r0 sub a(r2),r0 add w(r3),r0 sub a(r3),r0 jsr pc,allocate jsr pc,zero mov r1,6(sp) /result clr offset mov 2(sp),r1 /arg2 jsr pc,rewind / / work on next digit of arg2, starting over on arg1 / 1: mov 4(sp),r1 /arg1 jsr pc,rewind mov 2(sp),r1 /arg2 jsr pc,getchar bes 3f mov r0,r2 mov 6(sp),r1 /result jsr pc,rewind add offset,r(r1) clr 0(sp) /carry / / work on next digit of arg3 / form the product of the two digits, / add to what is already there and add in old carry / to generate new dit and new carry. / 2: mov 4(sp),r1 /arg1 jsr pc,getchar bes 2f mov r0,r3 mpy r2,r3 add (sp),r3 /carry mov 6(sp),r1 /result jsr pc,lookchar add r0,r3 mov r3,r1 clr r0 dvd $100.,r0 mov r0,(sp) /carry mov r1,r0 mov 6(sp),r1 /result jsr pc,alterchar br 2b / 2: inc offset tst (sp) /carry beq 1b mov 6(sp),r1 /result jsr pc,lookchar add (sp),r0 /carry jsr pc,alterchar br 1b / 3: / / change sign of result if necessary / tst outsign bpl 1f mov 6(sp),r1 /result jsr pc,chsign / / release dregs if necessary / 1: cmp 2(sp),14(sp) beq 1f mov 2(sp),r1 jsr pc,release 1: cmp 4(sp),12(sp) beq 1f mov 4(sp),r1 jsr pc,release 1: / / restore registers and return / tst (sp)+ tst (sp)+ tst (sp)+ mov (sp)+,r1 mov (sp)+,r0 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r5 rts pc / .bss outsign: .=.+2 offset: .=.+2 k: .=.+2 kptr: .=.+2 .text / sqrt: mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) mov r0,-(sp) / / check for zero or negative / mov w(r1),r2 sub a(r1),r2 / / look at the top one or two digits / mov r1,r3 jsr pc,fsfile jsr pc,backspace mov r0,r4 bit $1,r2 bne 2f mov r4,r1 mul $100.,r1 mov r1,r4 mov r3,r1 jsr pc,backspace add r0,r4 2: / / allocate space for result / inc r2 asr r2 mov r2,r0 jsr pc,allocate jsr pc,zero mov r2,r0 jsr pc,seekchar mov r1,r2 / / get high order digit of arg and square root it / mov $1,r0 2: sub r0,r4 blt 2f add $2,r0 br 2b 2: inc r0 asr r0 mov r0,r4 mov r2,r1 jsr pc,fsfile jsr pc,backspace cmp r4,$100.  blt 1f sub $100.,r4 mov r4,r0 jsr pc,alterchar mov $1,r0 jsr pc,putchar br 2f 1: mov r4,r0 jsr pc,alterchar 2: mov r1,-(sp) mov r3,-(sp) / / get successive approx. from Newton / 1: mov (sp),r3 /arg mov 2(sp),r2 /approx jsr pc,div3 mov r1,r3 jsr pc,add3 mov r1,-(sp) mov r3,r1 jsr pc,release mov r4,r1 jsr pc,release mov (sp)+,r1 mov sqtemp,r2 mov r1,r3 jsr pc,div3 mov r1,-(sp) mov r3,r1 jsr pc,release mov r4,r1 jsr pc,release mov (sp)+,r3 mov 2(sp),r1 jsr pc,length jsr pc,allocate mov 2(sp),r0 jsr pc,move jsr pc,chsign mov r1,r2 jsr pc,add3 jsr pc,fsfile jsr pc,backspace jsr pc,release mov r2,r1 jsr pc,release tst r0 bpl 2f / / loop if new < old mov 2(sp),r1 jsr pc,release mov r3,2(sp) br 1b / 2: mov r3,r1 jsr pc,release mov (sp)+,r1 jsr pc,release mov (sp)+,r1 mov (sp)+,r0 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 rts pc jsr pc,div3 mov r1,-(sp) mov r3,r1 jsr pc,release mov r4,r1 jsr pc,release mov (sp)+,r3 mov 2(sp),r1 jsr pc,length jsr pc,all/ / / routine to divide the two centennial numbers pointed / to by r2 (the divisor) and r3 (the dividend). / A pointer to the result is returned in r1. All other / registers are preserved. If the divisor is zero, zero / is returned and the carry bit is set. / Remainder is returned in r4 and has the sign / of the dividend. / / / mov divisor,r2 / mov dividend,r3 / jsr pc,div3 / mov r1,result / mov r4,remainder / / div3: mov r5,-(sp) mov r3,-(sp) /dividend mov r2,-(sp) /divisor mov r0,-(sp) tst -(sp) /result / / allocate space for result; allocate temps if necessary / clr r0 jsr pc,allocate mov r1,0(sp) /result / / / check for divisor zero / mov 4(sp),r2 /divisor mov w(r2),r0 sub a(r2),r0 bne 1f jmp eh 1: / / compute sign of result and make arguments positive / clr divsign mov r2,r1 jsr pc,length jsr pc,allocate mov r1,divisor mov r2,r0 jsr pc,move jsr pc,fsfile jsr pc,backspace bpl 1f 2: jsr pc,chsign mov r1,divisor com divsign 1: clr remsign mov r3,r1 jsr pc,length jsr pc,allocate mov r1,dividend mov r3,r0 jsr pc,move jsr pc,fsfile jsr pc,backspace bpl 1f 2: jsr pc,chsign mov r1,dividend com divsign com remsign 1: / / / find out how many digits in the quotient result / 1: mov dividend,r2 mov divisor,r3 mov w(r2),r0 sub a(r2),r0 add a(r3),r0 sub w(r3),r0 jlo bugout mov r0,divoffset mov 0(sp),r1 /result inc r0 jsr pc,seekchar clr r0 mov dividend,r1 jsr pc,putchar / / load r5 with binary divisor for finding / trial quotient digits. If leading digit of / divisor is <10, it is scaled / clr magic mov divisor,r1 jsr pc,fsfile jsr pc,backspace mov r0,r5 cmp r5,$10. bge 2f inc magic 2: mpy $100.,r5 jsr pc,backspace add r0,r5 tst magic beq 2f mov r5,r4 mpy $100.,r4 jsr pc,backspace add r0,r5 adc r4 asl r5 rol r4 dvd $25.,r4 mov r4,r5 2: / / compute trial quotient digit / 1: mov dividend,r1 jsr pc,fsfile jsr pc,backspace bec 9f; 4; 9: mov r0,r3 mpy $100.,r3 mov r3,r2 jsr pc,backspace add r0,r2 mpy $100.,r2 jsr pc,backspace add r0,r3 adc r2 tst divoffset bne 2f add $1,r3 adc r2 2: / tst magic beq 3f ashc $3,r2 3: mov r5,r0 tst divoffset beq 2f inc r0 2: dvd r0,r2 mov r2,trial / / / multiply divisor by trial digit / mov divisor,r1 jsr pc,rewind jsr pc,length inc r0 mov divxyz,r1 jsr pc,rewind clr -(sp) 2: mov divisor,r1 jsr pc,getchar bes 2f mov r0,r3 mpy trial,r3 add (sp),r3 /carry clr r2 dvd $100.,r2 mov r2,(sp) /carry mov r3,r0 mov divxyz,r1 jsr pc,alterchar br 2b 2: mov divxyz,r1 mov (sp)+,r0 jsr pc,alterchar 3: / / and subtract from dividend / jsr pc,rewind mov divoffset,r0 mov dividend,r1 jsr pc,seekchar clr -(sp) / 2: mov dividend,r1 jsr pc,lookchar bes 2f mov r0,r2 / mov divxyz,r1 jsr pc,getchar sub r0,r2 sub (sp),r2 clr (sp) mov r2,r0 bpl 3f add $100.,r0 mov $1.,(sp) 3: mov dividend,r1 jsr pc,alterchar br 2b / / put away the quotient digit / 2: mov (sp)+,divcarry mov 0(sp),r1 /result jsr pc,backspace mov trial,r0 jsr pc,alterchar jsr pc,backspace / / and go for another digit / dec divoffset bmi 1f mov dividend,r1 dec w(r1) cmp w(r1),a(r1) bhis 9f; 4; 9: jmp 1b / / fix up the result / 1: tst divcarry beq 1f mov trial,r0 dec r0 jsr pc,alterchar mov dividend,r1 mov $-1,r0 jsr pc,alterchar mov divisor,r2 mov dividend,r3 jsr pc,add3 mov r1,-(sp) mov r3,r1 jsr pc,release mov (sp)+,dividend 1: mov 0(sp),r1 /result jsr pc,rewind clr divcarry 1: jsr pc,lookchar bes 1f bic $!377,r0 add divcarry,r0 clr divcarry cmp r0,$100. blt 2f sub $100.,r0 inc divcarry 2: jsr pc,alterchar br 1b / 1: tst divcarry beq 1f mov $1.,r0 jsr pc,alterchar 1: jsr pc,fsfile 1: jsr pc,backspace bes 1f bne 1f mov r(r1),w(r1) br 1b 1: / / change sign of result if necessary / tst divsign bpl 1f jsr pc,chsign 1: mov dividend,r1 jsr pc,fsfile 1: jsr pc,backspace bes 1f bne 1f mov r(r1),w(r1) br 1b 1: bugout: tst remsign bpl 1f mov dividend,r1 jsr pc,chsign / / clean up junk, restore registers, and return / 1: mov divisor,r1 jsr pc,release mov (sp)+,r1 mov (sp)+,r0 mov (sp)+,r2 mov (sp)+,r3 mov dividend,r4 mov (sp)+,r5 clc rts pc / / / / .bss divisor: .=.+2 dividend: .=.+2 divxyz: .=.+2 divoffset:.=.+2 divcarry: .=.+2 divsign: .=.+2 trial: .=.+2 remsign: .=.+2 magic: .=.+2 .text / / / / routine to exponentiate the two centennial numbers / pointed to by r2 (the base) and r3 (the exponent). / A pointer to the result is returned in r1. / / mov base,r2 / mov exp,r3 / jsr pc,exp3 / mov r1,... / / / save registers / exp3: mov r3,-(sp) /exponent mov r2,-(sp) /base mov r0,-(sp) / / 1: mov $1,r0 jsr pc,allocate mov r1,-(sp) /accumulated result mov $1,r0 jsr pc,putchar / mov r2,r1 jsr pc,length jsr pc,allocate mov r1,-(sp) /powers of the base mov r2,r0 jsr pc,move / mov r3,r1 jsr pc,length jsr pc,allocate mov r1,-(sp) /exponent mov r3,r0 jsr pc,move jsr pc,fsfile clr exptemp jsr pc,backspace bpl 1f inc exptemp jsr pc,chsign / 1: mov 0(sp),r1 jsr pc,length beq 1f mov sqtemp,r2 mov 0(sp),r3 jsr pc,div3 mov r1,0(sp) mov r3,r1 jsr pc,release mov r4,r1 jsr pc,length jsr pc,release tst r0 beq 2f / / / mov 2(sp),r2 mov 4(sp),r3 jsr pc,mul3 mov r1,4(sp) mov r3,r1 jsr pc,release 2: mov 2(sp),r3 mov r3,r1 jsr pc,length jsr pc,allocate mov r1,r2 mov r3,r0 jsr pc,move jsr pc,mul3 mov r1,2(sp) mov r3,r1 jsr pc,release mov r2,r1 jsr pc,release br 1b 1: tst exptemp beq 1f mov 10(sp),r1 jsr pc,length bne 2f jmp eh 2: cmp r0,$1 blos 2f mov 4(sp),r1 jsr pc,create br 1f 2: jsr pc,rewind jsr pc,getchar cmp r0,$1 bgt 2f mov 4(sp),r1 jsr pc,create jsr pc,putchar br 1f 2: mov 4(sp),r1 jsr pc,create 1: mov (sp)+,r1 jsr pc,release mov (sp)+,r1 jsr pc,release mov (sp)+,r1 / mov (sp)+,r0 mov (sp)+,r2 mov (sp)+,r3 rts pc / .bss exptemp: .=.+2 .text / jsr pc,mul3 mov r1,2(sp) mov r3,r1 jsr pc,release mov r2,r1 jsr pc,release br 1b 1: tst exptemp beq 1f mov 10(sp),r1 jsr pc,length bne 2f jmp eh 2: cmp r0,$1 blos 2f mov 4(sp),r1 jsr pc,create br 1f 2: jsr pc,rewind jsr pc,getchar cmp r0,$.globl getchar .globl stats .globl lookchar .globl fsfile .globl seekchar .globl backspace .globl putchar .globl alterchar .globl move .globl rewind .globl create .globl zero .globl allocate .globl release .globl collect .globl getword, putword .globl length, position .globl w, r, a, l / testing = 0 / / / routine to return the length of a string / / mov ...,r1 / jsr pc,length / mov r0,... / length: mov w(r1),r0 sub a(r1),r0 rts pc / / / routine to return the read pointer position / / mov ...,r1 / jsr pc,position / mov r0,... / position: mov r(r1),r0 sub a(r1),r0 rts pc / / / / / routine to get a word from the string / mov ...,r1 / jsr pc,getword / mov r0,... / getword: jsr pc,getchar bes noch movb r0,nchar jsr pc,getchar bec 2f dec r(r1) br noch 2: movb r0,nchar+1 mov nchar,r0 tst r0 /tst clears c-bit rts pc / / / routine to put a word onto the string / mov ...,r1 / mov ...,r0 / jsr pc,putword / putword: jsr pc,putchar swab r0 jsr pc,putchar swab r0 rts pc / .bss nchar: .=.+2 .text / / / / routine to read next character from string / pointed to by r1; character returned in r0 / c-bit set if character not available (end of file) / r1 is preserved / / mov ...,r1 / jsr pc,getchar / movb r0,... / getchar: jsr pc,lookchar bec 2f rts pc 2: inc r(r1) tst r0 /tst clears c-bit rts pc / noch: clr r0 sec rts pc / / routine to look at next character from string / pointed to by r1; character returned in r0 / c-bit set if character not available (end of file) / r1 is preserved / / mov ...,r1 / jsr pc,lookchar / movb r0,... / lookchar: .if testing jsr pc,plausible inc stats+6. .endif cmp w(r1),r(r1) blos noch movb *r(r1),r0 clc rts pc / plausible: cmp r1,$headers bhis 9f; 4; 9: cmp r1,$headend blo 9f; 4; 9: rts pc / / / / routine to move the read pointer of a string to a / specified point. If the string is not long enough, / the string is extended / / mov position,r0 / mov ...,r1 / jsr pc,seekchar / seekchar: mov r1,-(sp) mov r0,-(sp) .if testing jsr pc,plausible inc stats+10. .endif 1: mov (sp),r0 add a(r1),r0 cmp r0,l(r1) bhi 3f mov r0,r(r1) cmp r0,w(r1) blo 1f mov r0,w(r1) br 1f 3: mov (sp),r0 jsr pc,allocate mov 2(sp),r0 jsr pc,move jsr pc,swap jsr pc,release mov 2(sp),r1 br 1b 1: mov (sp)+,r0 mov (sp)+,r1 rts pc / / / routine to move read pointer of string to end of string / / mov ...,r1 / jsr pc,fsfile / fsfile: .if testing jsr pc,plausible inc stats+10. .endif mov w(r1),r(r1) rts pc / / / routine to read a string backwards / the read pointer is decremented before reading / / mov ...,r1 / jsr pc,backspace / mov r0,... / backspace: .if testing jsr pc,plausible inc stats+6. .endif cmp a(r1),r(r1) bhis noch dec r(r1) movb *r(r1),r0 clc rts pc / / / / / routine to put a character into the string / pointed to by r1; character in r0 / r0 and r1 are preserved. / / movb ch,r0 / mov ...,r1 / jsr pc,putchar / putchar: mov r1,-(sp) mov r0,-(sp) .if testing jsr pc,plausible inc stats+8. .endif 1: cmp w(r1),l(r1) blt 3f mov w(r1),r0 inc r0 sub a(r1),r0 /W-A+1 jsr pc,allocate mov 2(sp),r0 /r1 jsr pc,move jsr pc,swap jsr pc,release mov 2(sp),r1 /r1 cmp w(r1),l(r1) blt 3f jmp err / 3: movb (sp),*w(r1) inc w(r1) mov (sp)+,r0 tst (sp)+ rts pc / / swap: mov w(r1),-(sp) mov w(r0),w(r1) mov (sp),w(r0) mov r(r1),(sp) mov r(r0),r(r1) mov (sp),r(r0) mov a(r1),(sp) mov a(r0),a(r1) mov (sp),a(r0) mov l(r1),(sp) mov l(r0),l(r1) mov (sp)+,l(r0) rts pc / / / routine to alter a character in the string / pointed to by r1; character in r0 / r0 and r1 are preserved. / / movb ch,r0 / mov ...,r1 / jsr pc,alterchar / alterchar: mov r1,-(sp) mov r0,-(sp) .if testing jsr pc,preposterous inc stats+8. .endif 1: cmp r(r1),l(r1) blt 3f mov l(r1),r0 inc r0 sub a(r1),r0 /W-A+1 jsr pc,allocate mov 2(sp),r0 /r1 jsr pc,move jsr pc,swap jsr pc,release mov 2(sp),r1 /r1 cmp r(r1),l(r1) blt 3f jmp err / 3: movb (sp),*r(r1) inc r(r1) cmp r(r1),w(r1) ble 1f mov r(r1),w(r1) 1: mov (sp)+,r0 tst (sp)+ rts pc / / / routine to move the contents of one string / to another. / / mov source,r0 / mov dest,r1 / jsr pc,move / / on return, r1 points to the new string and should / be saved. r0 is preserved. / move: mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov w(r0),r2 sub a(r0),r2 /W-A mov l(r1),r3 sub a(r1),r3 /L-A cmp r2,r3 ble 1f mov r2,r0 jsr pc,allocate mov 2(sp),r0 /r1 jsr pc,swap jsr pc,release mov r0,r1 mov 0(sp),r0 /r0 / 1: mov a(r0),(r0) mov a(r1),(r1) 1: dec r2 blt 1f movb *(r0),*(r1) inc (r0) inc (r1)  br 1b / / fix up read ptr of new string / 1: mov r(r0),r2 sub a(r0),r2 add a(r1),r2 mov r2,r(r1) / / restore and return / mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 rts pc / / / routine to rewind read pointer of string / pointed to by r1 / / mov ...,r1 / jsr pc,rewind / rewind: .if testing jsr pc,plausible inc stats+10. .endif mov a(r1),r(r1) rts pc / / routine to rewind write pointer of string / pointed to by r1 / / mov ...,r1 / jsr pc,create / create: .if testing jsr pc,plausible inc stats+10. .endif mov a(r1),w(r1) mov a(r1),r(r1) rts pc / / / routine to zero a string / / mov ...,r1 / jsr pc,zero / zero: mov r0,-(sp) .if testing jsr pc,preposterous .endif mov a(r1),r0 1: cmp r0,l(r1) bhis 1f clrb (r0)+ br 1b 1: mov (sp)+,r0 rts pc / / pc,rewind / rewind: .if testing jsr pc,plausible inc stats+10. .endif mov a(r1),r(r1) rts pc / / routine to rewind write pointer of string / pointed to by r1 / / mov ...,r1 / jsr pc,create / create: .if testing jsr pc,plausible/ / / here to allocate a new block / / mov ...,r0 / jsr pc,allocate / mov r1,... / / requested size in bytes in r0 / pointer to header of allocated block returned in r1 / r0 is preserved / / convert to words, adjust for header, round up / to a power of two / / each block has a four-word header / W - write ptr (also used as link ptr in frlist) / R - read ptr / A - pointer to head of data / L - ptr to (end+1) of data w=0 r=2 a=4 l=6 / allocate: clr garbage mov r0,-(sp) mov r2,-(sp) tst stats bne 1f jsr pc,init 1: inc stats bne 9f; inc stats; 9: cmp r0,$strend-strbuf blos 9f; 4; 9: 1: cmp $8.,r0 blo 2f mov $3.,r0 br 1f 2: sub $1,r0 bmi 1f jsr pc,log2 add $1,r0 1: asl r0 /bite to word mov r0,-(sp) add $2,r0 cmp r0,$frend-frlist+2 blo zzz jmp err / / look on free list for block of required size / zzz: mov (sp),r0 tst frlist(r0) beq xxx / / found it, allocate and return / mov frlist(r0),r1 mov (r1),frlist(r0) mov a(r1),r0 mov r0,w(r1) /W mov r0,r(r1) /R tst (sp)+ mov (sp)+,r2 mov (sp)+,r0 rts pc / / no block of required size / look for larger block / xxx: tst hdrptr bne 1f mov r0,-(sp) jsr pc,morehd tst r0 bne out mov (sp)+,r0 1: tst (r0)+ cmp r0,$frend-frlist bhis www tst frlist(r0) bne yyy br xxx / / there are no larger blocks; must garbage collect / www: jsr pc,collect tst r0 bne zzz jsr pc,moresp tst r0 beq zzz / / out of space / out: mov $1,r0 sys write; 1f; 2f-1f jmp reset 1: 2: .even / / split larger block into two smaller pieces and / link together as smaller blocks in the free list. / yyy: mov frlist(r0),r1 mov (r1),frlist(r0) mov hdrptr,r2 bne 1f mov r0,-(sp) jsr pc,morehd tst r0 bne out mov (sp)+,r0 mov hdrptr,r2 1: mov (r2),hdrptr clr (r2) mov r2,(r1) mov r1,hdrptr(r0) mov l(r1),l(r2) mov l(r1),r0 sub a(r1),r0 asr r0 add a(r1),r0 mov r0,l(r1) mov r0,a(r2) br zzz / / / here to release a block / / mov ...,r1 / jsr pc,release / / pointer to block in r1 / release: / / discover that this is a plausible pointer / mov r0,-(sp) jsr pc,preposterous / / find free list index and link block to that entry / inc stats+2 mov frlist(r0),(r1) clr r(r1) mov r1,frlist(r0) clr r1 /self-defense mov (sp)+,r0 rts pc / / / jsr pc,collect / / coalesce free storage by rejoining paired blocks / on the free list. / zero is returned in r0 if no paired blocks were found. / collect: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) clr useful inc stats+4. clr r0 /start with smallest blocks /r0 contains frlist index loop1: mov $frlist,r1 add r0,r1 / / try next list member at this level / loop2: mov (r1),r3 beq advance /list is empty tst *(r1) /W beq advance /only one list element / / calculate address of buddy / mov a(r3),r4 mov $block,r2 1: cmp r4,(r2) blo 1f cmp r2,lblock beq 2f add $2,r2 br 1b 1: sub $2,r2 2: mov (r2),beg sub beg,r4 bit exp2(r0),r4 beq 2f bic exp2(r0),r4 br 1f 2: bis exp2(r0),r4 1: add beg,r4 / / and search for him / loop3: tst 0(r3) beq nocoal mov (r3),r2 cmp a(r2),r4 beq coal mov (r3),r3 br loop3 / / have found a pair; remove both blocks from list, / coalesce them, and put them on next higher list / coal: inc useful mov (r3),r4 mov (r4),(r3) /remove him from list mov (r1),r2 mov (r2),(r1) /remove the other one cmp a(r2),a(r4) bgt 1f mov r2,-(sp) mov r4,r2 mov (sp)+,r4 1: add exp2(r0),l(r4) clr r(r4) mov frlist+2(r0),(r4) mov r4,frlist+2(r0) mov hdrptr,(r2) mov r2,hdrptr clr r(r2) mov beg,a(r2) mov beg,l(r2) br loop2 / / no buddy found, try next block on this list / nocoal: mov (r1),r1 br loop2 / / advance to next free list / advance: tst (r0)+ cmp r0,$frend-frlist blo loop1 mov useful,r0 / / do we have enough headers to continue? / cmp garbage,$2 blo 1f mov $1,r0 sys write; 4f; 5f-4f jmp reset / 4: 5: .even / / / restore registers and return / 1: inc garbage mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 rts pc / .bss garbage: .=.+2 .text / / routine to get more space for strings / moresp: mov r2,-(sp) mov r1,-(sp) mov brk,r1 mov $block,r2 add nblock,r2 cmp r2,$blkend bhis rout mov r1,(r2) mov r1,lblock add $2,nblock add $10000,r1 mov r1,9f sys break;9:.. bes 2f mov hdrptr,r2 bne 1f jsr pc,morehd tst r0 beq 2f mov hdrptr,r2 1: mov (r2),hdrptr mov brk,a(r2) mov r1,brk mov r1,l(r2) clr r(r2) mov $10000,r0 jsr pc,log2 asl r0 mov frlist(r0),w(r2) mov r2,frlist(r0) clr r0 mov (sp)+,r1 mov (sp)+,r2 rts pc 2: mov $1,r0 mov (sp)+,r1 mov (sp)+,r2 rts pc / / routine to get move space for headers / morehd: mov r2,-(sp) mov brk,r0 mov $hblock,r2 add nhdr,r2 cmp r2,$hblkend bhis rout mov r0,(r2) mov r0,lhblock add $2,nhdr add $1024.,r0 mov r0,9f sys break;9:.. bes 2f mov brk,r2 mov r2,hdrptr mov r0,brk sub $8,r0 1: add $8,r2 mov r2,-8(r2) cmp r2,r0 blos 1b clr -8(r2) clr r0 mov (sp)+,r2 rts pc 2: mov $1,r0 mov (sp)+,r2 rts pc rout: mov $1,r0 sys write; 4f; 5f-4f jmp reset / 4: 5: .even / / routine to find integer part of log2(x) / / jsr pc,log2 / / r0 = log2(r0) / log2: mov r0,-(sp) bge 9f; 4; 9: mov $15.,r0 1: rol (sp) bmi 1f sob r0,1b 1: dec r0 tst (sp)+ rts pc / 0 /Don't move me, I'm exp(-1) exp2: 1;2;4;10;20;40;100;200;400;1000;2000;4000; 10000;20000;40000;100000 / / routine to discover whether r1 points to / a plausible header - to avoid ruination. / / r1 is preserved and r0 gets a suitable index for frlist / / jsr pc,preposterous / preposterous: mov r2,-(sp) mov $hblock,r2 1: cmp r1,(r2) blo 1f cmp (r2),lhblock beq 2f add $2,r2 br 1b 1: sub $2,r2 2: mov (r2),r2 add $1024.,r2 cmp r1,r2 blo 9f;4;9: mov $block,r2 1: cmp a(r1),(r2) blo 1f cmp (r2),lblock beq 2f add $2,r2 br 1b 1: sub $2,r2 2: cmp l(r1),(r2) bhis 9f;4;9: mov (r2),r2 add $10000,r2 cmp a(r1),r2 blo 9f;4;9: cmp l(r1),r2 blos 9f;4;9: mov (sp)+,r2 mov l(r1),r0 /L sub a(r1),r0 /A mov r0,-(sp) jsr pc,log2 asl r0 cmp exp2(r0),(sp) beq 9f; 4; 9: add $2,r0 cmp r0,$frend-frlist+2 blo 9f; 4; 9: sub $2,r0 mov r0,(sp) mov frlist(r0),r0 1: beq 1f cmp r0,r1 bne 9f; 4; 9: mov (r0),r0 br 1b 1: mov (sp)+,r0 rts pc / / / routine to initialize storage area, headers and / free list upon first call to allocate a block. / The entire storage area is formed into a single block. / init: mov r0,-(sp) mov r1,-(sp) / / form all the headers into a single list. / mov $headers,r0 mov r0,hdrptr 1: add $8,r0 mov r0,-8(r0) cmp r0,$headend-8 blos 1b clr -8(r0) mov $frlist,r0 1: clr (r0)+ cmp r0,$frend blo 1b / mov hdrptr,r1 mov (r1),hdrptr clr w(r1) mov $strbuf,r0 mov r0,a(r1) mov $strend-strbuf,r0 jsr pc,log2 asl r0 cmp r0,$frend-frlist blo 9f; 4; 9: mov r1,frlist(r0) mov exp2(r0),r0 add $strbuf,r0 mov r0,l(r1) mov $hdrptr,r1 1: mov (r1),r1 tst r1 beq 1f mov $strbuf,a(r1) mov $strbuf,l(r1) br 1b 1: mov $end,brk add $2,nblock mov $strbuf,block mov $strbuf,lblock mov $headers,hblock add $2,nhdr mov $headers,lhblock mov (sp)+,r1 mov (sp)+,r0 rts pc / / .bss nhdr: .=.+2 lhblock: .=.+2 hblock: .=.+20. hblkend: stats: .=.+16. useful: .=.+2 beg: .=.+2 lblock: .=.+2 nblock: .=.+2 block: .=.+40. blkend: brk: .=.+2 hdrptr: .=.+2 /do not move me frlist: .=hdrptr+32. frend: headers:.=hdrptr+1024. headend: strbuf: .=.+10000 strend: end: signal = 48. beq 1f mov $strbuf,a(r1) mov $strbuf,l(r1) br 1b 1: mov $end,brk add $2,nblock mov $strbuf,block mov $strbuf,lblock mov $headers,hblock add $2,nhdr mov $headers,lhblock mov (sp)+,r1 mov (sp)+,r0 rts pc / / .bss nhdr: .=.+2 lhblock: .=.scale = 20 define e(x){ auto a, b, c, d, e, g a=1 b=10 c=b d=1 e=1 for(a=1;1==1;a++){ b=b*x c=c*a+b d=d*a g = c/d if(g == e) return(g/10) e=g } } scale = 20 define s(x){ auto a, b, c, d, e, g, y y = -x*x a=1 b=x c=b d=1 e=1 for(a=3;1==1;a=a+2){ b=b*y c=c*a*(a-1) + b d=d*a*(a-1) g=c/d if(g==e) return(g) e=g } } scale = 20 define c(x){ auto a, b, c, d, e, g, y y = -x*x a=1 b=1 c=b d=1 e=1 for(a=2;1==1;a=a+2){ b=b*y c=c*a*(a-1) + b d=d*a*(a-1) g=c/d if(g==e) return(g) e=g } } scale = 20 define l(x){ auto a, b, c, d, e, f, g, u, s, t if(x <=0) return(1-10^scale) t = scale scale = 0 f = 1 s = x while(s > 0){ s = s/10 f = f + 1 } scale = t + f f=1 while(x > 2){ x = sqrt(x) f=f*2 } while(x < .5){ x = sqrt(x) f=f*2 } u = (x-1)/(x+1) s = u*u b = 2*f c = b d = 1 e = 1 for(a=3;1==1;a=a+2){ b=b*s c=c*a+d*b d=d*a g=c/d if(g==e){ scale = t return(u*c/d) } e=g } } scale = 20 define a(x){ auto a, b, c, d, e, f, g, s, t if(x==0) return(0) t = scale f=1 while(x > .5){ scale = scale + 1 x= -(1-sqrt(1.+x*x))/x f=f*2 } while(x < -.5){ scale = scale + 1 x = -(1-sqrt(1.+x*x))/x f=f*2 } s = -x*x b = f c = f d = 1 e = 1 for(a=3;1==1;a=a+2){ b=b*s c=c*a+d*b d=d*a g=c/d if(g==e){ scale = t return(x*c/d) } e=g } } scale = 20 define j(n,x){ auto a,b,c,d,e,g,i,s s= -x*x/4 if(n<0){ n= -n x= -x } a=1 c=1 for(i=1;i<=n;i++){ a=a*x c = c*2*i } b=a d=1 e=1 for(i=1;1;i++){ a=a*s b=b*i*(n+i) + a c=c*i*(n+i) g=b/c if(g==e){ return(g) } e=g } } cale + 1 x= -(1-sqrt(1.+x*x))/x f=f*2 } while(x < -.5){ scale = scale + 1 x = -(1-sqrt(1.+x*x))/x f=f*2 } s = -x*x b = f c = f d = 1 e = 1 for(a=3;1==1;a=a+2){ b=b*s c=c*a+d*b d=d*a g=c/d if(g==e){ scale = t return(x*c/d) } e=g } } scale = 20 define j(n,x){ auto a,b,c,d,e,g,i,s s= -x*x/4 if(n<0){ n= -n x= -x } a=1 c=1 for(i=1;i<=n;i++){ a=a*x c = c*2*i } b=a d=1 e=1 for(i=1;1;i++){ a=a*s (ZDw 5 _ @mȥ-d @m5[ @me5 @D7 y  5 ˋ @  A@   @m . 7% 8 7n%  @mȥ- D-  (    5%N   @m D- wTw P2f % Neg %& 77 77777 777 %  > fe % *x %&  p  }  jE Ne R LD  6w2w .AWpBe D  Z %  =L t4 A N& vN&   B-WpCae ee& $e%ww CNe2p b%& % Tfe fe %\` Z\ V   ww @N@& ww B8(1ʥA# 0= =Nf&* %@@o=  3 %  wT = =Nf %@@o  N  w  D̋ ̥%  %w w D  vu524 5fe %ww 7zD & 3223447 8 :":6e(    ww  N v   &  %ww C "  v   3rWp`D 7! 7! 7w~w zN , &  %w`w \XTP ew@w L100050_had_dir _had_sta L41>_printf _diff"L42_rename _xrm _remove _getuid _setuid L44L45D_msg2 _freeall _init"~initffilepilpwhich lookaheaL47L48Z_alloc L49*_opena"vL200074_openb"L51:L52n_rdline"$~openavmodpfuser_rdpfile _getlnam _equal L54L56L55_dorelta _permiss _dodelta ~openbpfile_opnl ~rdline$buflenpktptextlnno L59>L20011L200104L20012L60_readmod _move L62_getl L63_close L58_checkid"~checkidlinepL64 L66L68$_wrtctl"(~wrtctl(ctlctlrecpL71@_wrtopn"v_wrtrec ~wrtopnvpp1p2_zero _opnr _wrtend"~wrtendpL74L75L76_before",~before,pnL78~L79FL80PL81dL82j_after"~afterp_status"~statusL86_enter"~enterrl fill1fill2_ackrel L87_acklev _acknowl _clean_u"~clean_u_mkdelta"~mkdeltapktlevelL91L94L93_timenow _size L90L96~diffdeglenabpickfileafileblookaheaainfobinfoL98L106 _match" _choose"l _insert" _delete" L100L20014_take" L102L20017t L108 L20019 L110 L111 L20022 L97 L20021 _update"~match start2 degsubf1f2i1i2mark1 mark2stop1foundL113 L114` L115 L116Z L118 L112 L119 ~insert reclenf1f2mark2L121 L122 L20024J _ctlrec L124 L125~delete lenf1f2mark1L126 L20025 L20027 ~take lenplpL130( _free L131j L132z _numsame" ~numsame start1start2 numf1f2i1i2L20028 L135 L137 L139 _reldiff" L10008`L10009hL10010p~reldiff ab xL142L L141H L20030B _W#x_X#_Y#_Z#L10015~choosel deg valab ikavglineainfobinfocharsnsameL145 L20040 _ask" L144 L20034 L149 L20032 L150 L153L154~ask f1f2ab L158L20041L156L10017L10018 L160_answer"L10019XL10020\L162L163L164"~answerpresplnL166L1670L168L1696L170AL20042L1716L20046L177`L173D_getresp"bL172ZL175P~getrespblessonrespnextcL179jL178_getchr L181L182L183L185L186gL20047L10021L10022~updaterespL189jL194L191qL195wL196zfltused L163L164"~answerpresplnL166L1670L168L1696L170AL20042L1716L20046L177`L173D_getresp"bL172ZL175P~getrespblessonrespnextcL179jL178_getchr L181L182L183L185L186gL20047L10021L10022~updatesignal = 48. testing = 0 / / command interpreter for form letter editor / / / command: sys signal; 2; inter jsr pc,initl mov sp,spi loop: mov spi,sp mov $buffer,r2 clr r4 clr iflag 1: jsr pc,tfiget cmpb $' ,r0 beq 1f cmpb $'\n,r0 bne 2f clrb (r2) br 4f 2: movb r0,(r2)+ br 1b 1: clrb (r2) mov $argc,r3 3: mov $arg,r2 2: jsr pc,tfiget cmpb $' ,r0 beq 1f cmpb $'\n,r0 beq 1f movb r0,(r2)+ br 2b 1: clrb (r2)+ inc r4 1: movb -(r2),sv cmp r2,$arg blos 1f movb -(r2),-(sp) movb sv,1(sp) cmp r2,$arg bhi 1b mov sp,(r3)+ br 2f 1: clrb -(sp) movb sv,1(sp) mov sp,(r3) add $1,(r3)+ 2: cmpb r0,$'\n bne 3b 1: mov -(r3),-(sp) cmp r3,$argc bhi 1b 4: mov r4,-(sp) 3: clr r0 mov $tabl,r4 2: mov (r4)+,r1 cmp r4,$tend bhi error add $2,r0 mov $buffer,r2 1: cmpb (r1)+,(r2)+ bne 2b tstb (r1) bne 1b tstb (r2) bne 2b sub $2,r0 add $jtable,r0 clr vflag clr qflag jmp *(r0) / error: mov $1,r0 sys write; err; 2 br loop / / tabl: c1; c2; c3; c4; c5; c6; c7; c8; tend: 0 c1: c2: c3: c4: c5: c6: c7: c8: err: endt: .even jtable: list; listf; ed; remove; rename; fin; q; memck; spi: .=.+2 sv: .=.+2 r4,-(sp) 3: clr r0 mov $tabl,r4 2: mov (r4)+,r1 cmp r4,$tend bhi error add $2,r0 mov $buffer,r2 1: cmpb (r1)+,(r2)+ bne 2b tstb (r1) bne 1b tstb (r2) bne 2b sub $2,r0 add $jtable,r0 clr vflag clr qflag jmp *(r0) / error: mov $1,r0 sys write; err; 2 br loop / / tabl: c1; c2; c3; c4; c5; c6; c7; c8; tend: 0 c1: .even ftemp: erm: .even tmpw: .=.+2 tmpr: .=.+2 / / remove a 'file' from memory / remove: mov (sp)+,r3 bgt 5f mov $1,vflag mov asmem,r1 jsr pc,rewind mov r(r1),-(sp) 4: tst iflag beq 1f jmp loop 1: jsr pc,getword bes 4f mov r0,r2 jsr pc,ask bec 1f mov r(r1),(sp) br 4b 1: jsr pc,getword br 2f 5: mov (sp),r0 jsr pc,getspq bec 2f tst qflag blt 6f mov (sp),r1 jsr pc,nothere br 3f 2: mov r0,r1 jsr pc,release mov r2,r1 jsr pc,release jsr pc,rm 3: tst vflag bne 3f tst iflag beq 1f jmp loop 1: tst qflag bgt 5b 6: tst (sp)+ dec r3 bgt 5b jmp loop 3: mov asmem,r1 mov (sp),r(r1) br 4b 4: tst (sp)+ jmp loop / / rename a 'file' / rename: mov (sp)+,r3 bne 1f jmp error 1: sub $2,r3 blt 1f 5: mov (sp),r0 jsr pc,getsp bes 4f tst (sp)+ sub $4,r(r1) mov (sp),r0 mov r2,-(sp) mov r(r1),-(sp) jsr pc,getsp bes 3f mov r2,-(sp) mov r0,r1 jsr pc,release jsr pc,rm mov (sp)+,r0 mov (sp)+,r(r1) jsr pc,alterword mov (sp)+,r1 jsr pc,release br 5f 3: mov (sp)+,r(r1) mov (sp)+,r1 jsr pc,release mov $2,r0 jsr pc,allocate mov (sp)+,r2 2: movb (r2)+,r0 beq 2f jsr pc,putchar br 2b 2: mov r1,r0 mov asmem,r1 jsr pc,alterword 5: tst iflag beq 2f jmp loop 2: tst r3 beq 2f sub $2,r3 bge 5b 1: tst (sp)+ jmp error 2: jmp loop 4: mov (sp)+,r1 jsr pc,nothere tst (sp)+ br 5b / / list contents of asmem / list: mov $buffer,r2 movb $'\n,(r2)+ jsr pc,output mov (sp)+,r3 beq 1f mov $1,vflag 5: tst iflag beq 2f jmp loop 2: mov (sp),r0 jsr pc,getspq bes 4f mov r2,r1 br 3f 1: mov asmem,r1 jsr pc,fsfile sub $2,r(r1) 2: tst iflag bne 2f jsr pc,backword bes 2f mov r0,r1 3: jsr pc,getn movb $'\n,(r2)+ jsr pc,output tst vflag bne 1f mov asmem,r1 sub $2,r(r1) br 2b 1: tst qflag bgt 5b 4: tst (sp)+ dec r3 bgt 5b 2: mov $buffer,r2 movb $'\n,(r2)+ jsr pc,output jmp loop / / list a 'file / listf: mov (sp)+,r3 bgt 4f jmp error 4: mov (sp),r0 jsr pc,getspq bes 3f mov r0,r4  mov r2,r1 jsr pc,rewind mov $buffer,r2 movb $'\n,(r2)+ 1: jsr pc,getchar bes 1f movb r0,(r2)+ cmp r2,$bufend blo 1b jsr pc,output br 1b 1: mov r4,r1 jsr pc,rewind movb $':,(r2)+ cmp r2,$bufend blo 2f jsr pc,output 2: movb $'\n,(r2)+ 1: tst iflag beq 2f jmp loop 2: cmp r2,$bufend blo 2f jsr pc,output 2: jsr pc,getchar bes 1f movb r0,(r2)+ br 1b 1: jsr pc,output 3: tst qflag bgt 4b tst (sp)+ dec r3 bgt 4b mov $buffer,r2 movb $'\n,(r2)+ jsr pc,output jmp loop / fin: jsr pc,flush jsr pc,whead 4 q: jsr pc,flush jsr pc,whead sys exit memck: mov (sp)+,r3 2: ble 2f mov (sp)+,r1 cmpb (r1),$'p bne 1f bis $1,vflag br 3f 1: cmpb (r1),$'f bne 3f bis $2,vflag 3: dec r3 br 2b 2: clr freeh mov $freeb,r2 1: clr (r2)+ cmp r2,$freen blo 1b mov $headers,r2 2: cmp l(r2),$hsz beq 6f jsr pc,ck bec 1f cmp r2,asmem beq 1f mov asmem,r1 jsr pc,rewind clr r3 4: inc r3 jsr pc,getword bes 5f cmp r0,r2 bne 4b 6: inc freeh 1: cont: add $8.,r2 cmp r2,$headend-4 blo 2b mov asmem,r1 jsr pc,rewind 4: jsr pc,getword bes 4f tst r(r0) beq 2f mov r0,r2 jsr pc,ck bes 4b 2: sub $hblk,r0 jsr r5,oct mov $1,r0 sys write; re; 24. cmp vflag,$1 beq 4b bit $1,r3 beq 2f jsr pc,getword mov r0,r1 jsr pc,release br 3f 2: jsr pc,backword add $4,r(r1) mov r0,r1 jsr pc,release 3: jsr pc,rm clr r3 br 4b 4: mov freeh,r0 jsr r5,decml mov $1,r0 sys write; frh; 14. mov $freeb,r2 mov $1,r3 6: cmp r2,$freen bhis 6f mov (r2)+,r0 beq 3f jsr r5,decml mov $1,r0 sys write; frb; 18. mov r3,r0 jsr r5,decml mov $1,r0 sys write; lf; 1. 3: asl r3 br 6b 6: mov $1,r0 sys write; lf; 1. jmp loop 5: mov r2,r0 sub $hblk,r0 jsr r5,oct mov $1,r0 sys write; un; 26. tst vflag beq 1b mov r2,r1 cmp vflag,$2 beq 3f jsr pc,rewind mov $buffer,r2 2: jsr pc,getchar bes 2f movb r0,(r2)+ cmp r2,$buffer+80. blo 2b jsr pc,output br 2b 2: movb $'\n,(r2)+ jsr pc,output mov r1,r2 cmp vflag,$1 bne 3f jmp cont 3: jsr pc,release jmp cont / interrupt: 4 / un: < header not accounted for\n> re: < part of asmem released\n> lf: <\n> frh: < free headers\n > frb: < free blocks size > endc: .even loop 5: mov r2,r0 sub $hblk,r0 jsr r5,oct mov $1,r0 sys write; un; 26. tst vflag beq 1b mov r2,r1 cmp vflag,$2 beq 3f jsr pc,rewind mov $buffer,r2 2: jsr pc,getchar bes 2f movb r0,(r2)+ cmp r2,$buffer+80. blo 2b jsr pc,output br 2b 2: movb $'\n,(r2)+ jsr pc,output mov r1,r2 cmp vflag,$1 bne 3f jmp cont 3: jsr pc,release jmp cont / interrupt: 4 / un:rti = 2 .globl rm .globl ck .globl loop .globl oct .globl argc .globl arg .globl tfiget .globl asmem .globl qflag .globl vflag .globl getspq .globl q .globl ask .globl getword .globl r .globl w .globl output .globl buffer .globl bufend .globl fv .globl getsp .globl release .globl nothere .globl getn .globl getchar .globl rewind .globl iflag .globl inter / output buffer / r2 = last char in buffer + 1 / r2 returned at beginning of buffer / output: sub $buffer,r2 blos 1f mov r2,0f mov $1,r0 sys write; buffer; 0:.. mov $buffer,r2 1: rts pc / / / routine to find the string pointed to by r0 / in either memory or curly / r1 = where to look / / returns error set if string not there / returns r1 = header of string if there getsp: mov r0,-(sp) mov asmem,r1 jsr pc,rewind /memory 3: jsr pc,getword bes 1f mov r0,r1 jsr pc,rewind mov (sp),r2 2: jsr pc,getchar bes 2f tstb (r2) beq 4f cmpb r0,(r2)+ beq 2b 4: mov asmem,r1 add $2,r(r1) br 3b 2: tstb (r2) bne 4b mov r1,r2 mov asmem,r1 jsr pc,getword tst (sp)+ rts pc 1: mov (sp)+,r0 sec rts pc / / finds header of string with name same as that pointed to by r0 / taking into account ? and * getspq: mov r0,-(sp) mov asmem,r1 tst qflag bgt 1f jsr pc,rewind 1: jsr pc,getword bes 1f mov r0,r1 jsr pc,rewind mov (sp),r2 2: cmpb (r2),$'* bne 3f clr strflg mov $2,qflag inc r2 tstb (r2) beq 6f mov r2,ch 3: jsr pc,getchar bes 2f tstb (r2) bne 3f cmp $2,qflag bne 4f mov ch,r2 3: cmpb (r2),$'? bne 3f inc r2 tst qflag bne 2b mov $1,qflag br 2b 3: cmpb r0,(r2)+ bne 5f inc strflg br 2b 5: cmp $2,qflag bne 4f tst strflg bne 4f dec r2 br 2b 4: mov asmem,r1 add $2,r(r1) br 1b 2: tstb (r2) bne 4b 6: mov r1,r2 mov asmem,r1 jsr pc,getword tst (sp)+ rts pc 1: mov $-1.,qflag mov (sp)+,r0 sec rts pc / / tfiget / jsr r5,tfiget / tfiget: clr r0 sys read; ch; 1 bes 1f tst iflag beq 9f; jmp loop; 9: tst r0 beq 1f movb ch,r0 rts pc 1: jmp q / / routine to print file name and error message / r2 = next free byte in buffer / nothere: mov $buffer,r2 1: tstb (r1) beq 1f movb (r1)+,(r2)+ br 1b 1: sub $buffer,r2 mov r2,0f mov $1,r0 sys write; buffer; 0:.. mov $1,r0 sys write; err4; 16. rts pc / / / routine to put characters from string in buffer / r1 = header of string / on return r2 = next free byte in buffer / getn: mov $buffer,r2 jsr pc,rewind 1: jsr pc,getchar bes 1f movb r0,(r2)+ cmp r2,$bufend bhis 1f br 1b 1: rts pc / ask: mov r2,-(sp) mov r0,r1 jsr pc,getn movb $' ,(r2)+ jsr pc,output jsr pc,tfiget cmpb $'\n,r0 bne 1f 2: mov asmem,r1 add $2,r(r1) mov (sp)+,r2 sec rts pc 1: cmpb r0,$'y beq 4f cmpb r0,$'q beq 3f 1: tst iflag bne 2b jsr pc,tfiget cmpb $'\n,r0 bne 1b br 2b 4: tst iflag bne 2b jsr pc,tfiget cmpb $'\n,r0 bne 1b mov asmem,r1 mov (sp)+,r2 clc rts pc 3: tst iflag bne 2b jsr pc,tfiget cmpb $'\n,r0 bne 1b mov (sp)+,r2 jmp loop inter: inc iflag rti / to remove an entry from asmem - r points to name ptr / rm: mov r3,-(sp) mov asmem,r1 mov r(r1),r3 sub $4,r(r1) mov r(r1),r2 mov r2,-(sp) 1: mov r3,r(r1) jsr pc,getword bes 1f mov r(r1),r3 mov r2,r(r1) jsr pc,alterword mov r(r1),r2 br 1b 1: mov r2,w(r1) mov (sp)+,r(r1) mov (sp)+,r3 rts pc / / check that header pointed to by r2 released / ck: mov r2,-(sp) mov l(r2),r0 sub a(r2),r0 sub $hblk,r2 jsr pc,log2 asl r0 mov r0,ch mov frlist(r0),r0 1: beq 1f cmp r2,r0 beq 2f add $hblk,r0 mov (r0),r0 br 1b 2: mov ch,r0 inc freeb(r0) mov (sp)+,r2 rts pc 1: mov (sp)+,r2 sec rts pc oct: mov r1,-(sp) mov r0,r1 clr r0 div $8.,r0 mov r1,-(sp) add $'0,(sp) tst r0 beq 1f jsr r5,oct 1: movb (sp)+,ch mov $1,r0 sys write; ch; 1 mov (sp)+,r1 rts r5 decml: mov r1,-(sp) mov r0,r1 clr r0 div $10.,r0 mov r1,-(sp) add $'0,(sp) tst r0 beq 1f jsr r5,decml 1: movb (sp)+,ch mov $1,r0 sys write; ch; 1 mov (sp)+,r1 rts r5 / / iflag: 0 qflag: 0 vflag: 0 .data err4: < not in memory.\n> err1: end1: .even .bss freeh: .=.+2 freeb: .=.+32. freen: ch: .=.+2 strflg: .=.+2 buffer: .=.+512. bufend: .=.+2 argc = buffer + 20. arg = buffer + 256. fv: .=.+2 .text r5,oct 1: movb (sp)+,ch mov $1,r0 sys write; ch; 1 mov (sp)+,r1 rts r5 decml: mov r1,-(sp) mov r0,r1 clr r0 div $10.,r0 mov r1,-(sp) add $'0,(sp) tst r0 beq 1f jsr r5,decml 1: movb (sp)+,ch mov $1,r0 sys write; ch; 1 mov (sp)+,r1 rts r5 / / iflag: 0 qflag: 0 vflag: 0 .data err4: < not in memory.\n> err1: end1: .even .bss freeh: .=.+2 freeb: .=.+32. freen: ch: .=.+2 strflg/*modified for Commercial II*/ char Bw[256-32] { /*Times Bold widths*/ 12, /*space*/ 13, /*!*/ 0, /*"*/ 0, /*#*/ 18, /*$*/ 28, /*%*/ 27, /*&*/ 12, /*' close*/ 16, /*(*/ 16, /*)*/ 18, /***/ 36, /*+*/ 12, /*,*/ 14, /*- hyphen*/ 12, /*.*/ 18, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 13, /*:*/ 13, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 22, /*?*/ 0, /*@*/ 28+0200, /*A*/ 26+0200, /*B*/ 26+0200, /*C*/ 29+0200, /*D*/ 25+0200, /*E*/ 23+0200, /*F*/ 28+0200, /*G*/ 32+0200, /*H*/ 16+0200, /*I*/ 21+0200, /*J*/ 28+0200, /*K*/ 25+0200, /*L*/ 36+0200, /*M*/ 30+0200, /*N*/ 29+0200, /*O*/ 25+0200, /*P*/ 29+0300, /*Q*/ 28+0200, /*R*/ 23+0200, /*S*/ 25+0200, /*T*/ 29+0200, /*U*/ 27+0200, /*V*/ 36+0200, /*W*/ 27+0200, /*X*/ 28+0200, /*Y*/ 27+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 12, /*` open*/ 19, /*a*/ 19+0200, /*b*/ 16, /*c*/ 19+0200, /*d*/ 17, /*e*/ 13+0200, /*f*/ 18+0100, /*g*/ 22+0200, /*h*/ 12+0200, /*i*/ 12+0300, /*j*/ 23+0200, /*k*/ 12+0200, /*l*/ 32, /*m*/ 22, /*n*/ 18, /*o*/ 20+0100, /*p*/ 19+0100, /*q*/ 15, /*r*/ 17, /*s*/ 13+0200, /*t*/ 21, /*u*/ 19, /*v*/ 27, /*w*/ 21, /*x*/ 19+0100, /*y*/ 17, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 28, /*1/4*/ 28, /*1/2*/ 28, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 23, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ 15, /*degree*/ 20, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 19, /*cent*/ }; phen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 28, /*1/4*/ 28, /*1/2*/ 28, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 23, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ /*modified for Commercial II*/ char CEw[256-32] { /*Century Expanded widths*/ 12, /*space*/ 13, /*!*/ 0, /*"*/ 20, /*#*/ 18, /*$*/ 24, /*%*/ 27, /*&*/ 9, /*' close*/ 15, /*(*/ 15, /*)*/ 16, /***/ 27, /*+*/ 9, /*,*/ 14, /*- hyphen*/ 9, /*.*/ 12, /*/*/ 18+0200, /*0*/ 18+0200, /*1*/ 18+0200, /*2*/ 18+0200, /*3*/ 18+0200, /*4*/ 18+0200, /*5*/ 18+0200, /*6*/ 18+0200, /*7*/ 18+0200, /*8*/ 18+0200, /*9*/ 13, /*:*/ 13, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 19, /*?*/ 30, /*@*/ 28+0200, /*A*/ 25+0200, /*B*/ 25+0200, /*C*/ 27+0200, /*D*/ 26+0200, /*E*/ 25+0200, /*F*/ 26+0200, /*G*/ 29+0200, /*H*/ 15+0200, /*I*/ 20+0200, /*J*/ 28+0200, /*K*/ 25+0200, /*L*/ 32+0200, /*M*/ 29+0200, /*N*/ 25+0200, /*O*/ 24+0200, /*P*/ 26+0300, /*Q*/ 26+0200, /*R*/ 22+0200, /*S*/ 24+0200, /*T*/ 28+0200, /*U*/ 28+0200, /*V*/ 36+0200, /*W*/ 27+0200, /*X*/ 27+0200, /*Y*/ 24+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 9, /*` open*/ 18, /*a*/ 19+0200, /*b*/ 16, /*c*/ 19+0200, /*d*/ 17, /*e*/ 13+0200, /*f*/ 20+0100, /*g*/ 19+0200, /*h*/ 10+0200, /*i*/ 12+0300, /*j*/ 20+0200, /*k*/ 10+0200, /*l*/ 29, /*m*/ 19, /*n*/ 17, /*o*/ 19+0100, /*p*/ 19+0100, /*q*/ 16, /*r*/ 15, /*s*/ 14+0200, /*t*/ 19, /*u*/ 19, /*v*/ 27, /*w*/ 19, /*x*/ 20+0100, /*y*/ 17, /*z*/ 0, /*{*/ 5, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 24, /*1/4*/ 24, /*1/2*/ 24, /*3/4*/ 27, /*minus*/ 20, /*fi*/ 20, /*fl*/ 22, /*ff*/ 30, /*ffi*/ 30, /*ffl*/ 13, /*degree*/ 18, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 18, /*cent*/ }; phen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 24, /*1/4*/ 24, /*1/2*/ 24, /*3/4*/ 27, /*minus*/ 20, /*fi*/ 20, /*fl*/ 22, /*ff*/ 30, /*ffi*/ 30, /*f/*modified for Commercial II*/ char CKw[256-32] { /*Century Bold Italic widths (CK)*/ 12, /*space*/ 14, /*!*/ 0, /*"*/ 0, /*#*/ 19, /*$*/ 31, /*%*/ 30, /*&*/ 10, /*' close*/ 18, /*(*/ 18, /*)*/ 18, /***/ 27, /*+*/ 10, /*,*/ 14, /*- hyphen*/ 10, /*.*/ 11, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 13, /*:*/ 13, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 21, /*?*/ 0, /*@*/ 27+0200, /*A*/ 27+0200, /*B*/ 25+0200, /*C*/ 28+0200, /*D*/ 26+0200, /*E*/ 24+0200, /*F*/ 27+0200, /*G*/ 29+0200, /*H*/ 15+0200, /*I*/ 20+0200, /*J*/ 29+0200, /*K*/ 25+0200, /*L*/ 31+0200, /*M*/ 27+0200, /*N*/ 27+0200, /*O*/ 26+0200, /*P*/ 28+0300, /*Q*/ 29+0200, /*R*/ 22+0200, /*S*/ 25+0200, /*T*/ 28+0200, /*U*/ 25+0200, /*V*/ 35+0200, /*W*/ 26+0200, /*X*/ 27+0200, /*Y*/ 24+0200, /*Z*/ 14, /*[*/ 0, /*\*/ 14, /*]*/ 0, /*^*/ 0, /*_*/ 10, /*` open*/ 21, /*a*/ 19+0200, /*b*/ 18, /*c*/ 20+0200, /*d*/ 18, /*e*/ 14+0200, /*f*/ 19+0100, /*g*/ 21+0200, /*h*/ 12+0200, /*i*/ 13+0300, /*j*/ 21+0200, /*k*/ 13+0200, /*l*/ 30, /*m*/ 21, /*n*/ 19, /*o*/ 20+0100, /*p*/ 20+0100, /*q*/ 15, /*r*/ 16, /*s*/ 14+0200, /*t*/ 21, /*u*/ 19, /*v*/ 27, /*w*/ 22, /*x*/ 20+0100, /*y*/ 17, /*z*/ 0, /*{*/ 5, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 31, /*1/4*/ 31, /*1/2*/ 31, /*3/4*/ 27, /*minus*/ 23, /*fi*/ 23, /*fl*/ 22, /*ff*/ 19, /*en*/ 33, /*paragraph*/ 15, /*degree*/ 19, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 23, /*registered*/ 23, /*copywrite*/ 0, 19, /*cent*/ }; / 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 31, /*1/4*/ 31, /*1/2*/ 31, /*3/4*/ 27, /*minus*/ 23, /*fi*/ 23, /*fl*/ 22, /*ff*/ 19, /*en*//*modified for Commercial II*/ char Gw[256-32] { /*Geneva Regular widths*/ 12, /*space*/ 12, /*!*/ 0, /*"*/ 0, /*#*/ 23, /*$*/ 28, /*%*/ 25, /*&*/ 9, /*' close*/ 13, /*(*/ 13, /*)*/ 16, /***/ 36, /*+*/ 8, /*,*/ 15, /*- hyphen*/ 8, /*.*/ 15, /*/*/ 23+0200, /*0*/ 23+0200, /*1*/ 23+0200, /*2*/ 23+0200, /*3*/ 23+0200, /*4*/ 23+0200, /*5*/ 23+0200, /*6*/ 23+0200, /*7*/ 23+0200, /*8*/ 23+0200, /*9*/ 12, /*:*/ 12, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 25, /*?*/ 0, /*@*/ 25+0200, /*A*/ 26+0200, /*B*/ 27+0200, /*C*/ 26+0200, /*D*/ 24+0200, /*E*/ 22+0200, /*F*/ 29+0200, /*G*/ 27+0200, /*H*/ 11+0200, /*I*/ 20+0200, /*J*/ 26+0200, /*K*/ 22+0200, /*L*/ 32+0200, /*M*/ 27+0200, /*N*/ 29+0200, /*O*/ 24+0200, /*P*/ 29+0300, /*Q*/ 26+0200, /*R*/ 25+0200, /*S*/ 23+0200, /*T*/ 27+0200, /*U*/ 24+0200, /*V*/ 35+0200, /*W*/ 25+0200, /*X*/ 26+0200, /*Y*/ 23+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 9, /*` open*/ 21, /*a*/ 22+0200, /*b*/ 21, /*c*/ 22+0200, /*d*/ 21, /*e*/ 12+0200, /*f*/ 21+0100, /*g*/ 22+0200, /*h*/ 10+0200, /*i*/ 10+0300, /*j*/ 21+0200, /*k*/ 10+0200, /*l*/ 31, /*m*/ 22, /*n*/ 21, /*o*/ 22+0100, /*p*/ 22+0100, /*q*/ 14, /*r*/ 20, /*s*/ 12+0200, /*t*/ 22, /*u*/ 19, /*v*/ 28, /*w*/ 20, /*x*/ 20+0100, /*y*/ 18, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 15, /*hyphen*/ 27, /*bullet*/ 36, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 30, /*1/4*/ 30, /*1/2*/ 30, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 24, /*ff*/ 34, /*ffi*/ 34, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 21, /*registered*/ 21, /*copywrite*/ 0, 23, /*cent*/ }; phen*/ 27, /*bullet*/ 36, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 30, /*1/4*/ 30, /*1/2*/ 30, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 24, /*ff*/ 34, /*ffi*/ 34, /*ffl*/ char W10[256-32] { /*Genevia Regular Italic (GI) widths #803-033B*/ 13, /*space*/ 13, /*!*/ 0, /*"*/ 0, /*#*/ 23, /*$*/ 30, /*%*/ 26, /*&*/ 9, /*' close*/ 13, /*(*/ 13, /*)*/ 15, /***/ 36, /*+*/ 8, /*,*/ 14, /*- hyphen*/ 8, /*.*/ 11, /*/*/ 23+0200, /*0*/ 23+0200, /*1*/ 23+0200, /*2*/ 23+0200, /*3*/ 23+0200, /*4*/ 23+0200, /*5*/ 23+0200, /*6*/ 23+0200, /*7*/ 23+0200, /*8*/ 23+0200, /*9*/ 12, /*:*/ 12, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 24, /*?*/ 0, /*@*/ 25+0200, /*A*/ 25+0200, /*B*/ 28+0200, /*C*/ 26+0200, /*D*/ 23+0200, /*E*/ 21+0200, /*F*/ 29+0200, /*G*/ 26+0200, /*H*/ 11+0200, /*I*/ 20+0200, /*J*/ 25+0200, /*K*/ 22+0200, /*L*/ 31+0200, /*M*/ 27+0200, /*N*/ 29+0200, /*O*/ 23+0200, /*P*/ 29+0300, /*Q*/ 26+0200, /*R*/ 25+0200, /*S*/ 22+0200, /*T*/ 26+0200, /*U*/ 24+0200, /*V*/ 33+0200, /*W*/ 25+0200, /*X*/ 24+0200, /*Y*/ 23+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 9, /*` open*/ 21, /*a*/ 22+0200, /*b*/ 21, /*c*/ 22+0200, /*d*/ 21, /*e*/ 12+0200, /*f*/ 22+0100, /*g*/ 22+0200, /*h*/ 10+0200, /*i*/ 10+0300, /*j*/ 20+0200, /*k*/ 10+0200, /*l*/ 32, /*m*/ 22, /*n*/ 22, /*o*/ 22+0100, /*p*/ 22+0100, /*q*/ 13, /*r*/ 20, /*s*/ 12+0200, /*t*/ 22, /*u*/ 19, /*v*/ 28, /*w*/ 20, /*x*/ 19+0100, /*y*/ 18, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 36, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 30, /*1/4*/ 30, /*1/2*/ 30, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 24, /*ff*/ 34, /*ffi*/ 34, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 21, /*registered*/ 21, /*copywrite*/ 0, 23, /*cent*/ }; phen*/ 27, /*bullet*/ 36, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 30, /*1/4*/ 30, /*1/2*/ 30, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 24, /*ff*/ 34, /*ffi*/ 34, /*ffl*/ 14, /*/*Geneva Medium (similar to Helvetica Medium)*/ char W11[256-32] { /*Geneva Medium widths*/ 14, /*space*/ 14, /*!*/ 0, /*"*/ 0, /*#*/ 25, /*$*/ 29, /*%*/ 27, /*&*/ 10, /*' close*/ 15, /*(*/ 15, /*)*/ 17, /***/ 27, /*+*/ 10, /*,*/ 17, /*- hyphen*/ 10, /*.*/ 17, /*/*/ 25+0200, /*0*/ 25+0200, /*1*/ 25+0200, /*2*/ 25+0200, /*3*/ 25+0200, /*4*/ 25+0200, /*5*/ 25+0200, /*6*/ 25+0200, /*7*/ 25+0200, /*8*/ 25+0200, /*9*/ 14, /*:*/ 14, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 27, /*?*/ 0, /*@*/ 27+0200, /*A*/ 27+0200, /*B*/ 29+0200, /*C*/ 28+0200, /*D*/ 24+0200, /*E*/ 23+0200, /*F*/ 29+0200, /*G*/ 27+0200, /*H*/ 12+0200, /*I*/ 22+0200, /*J*/ 27+0200, /*K*/ 23+0200, /*L*/ 32+0200, /*M*/ 28+0200, /*N*/ 30+0200, /*O*/ 25+0200, /*P*/ 30+0300, /*Q*/ 26+0200, /*R*/ 26+0200, /*S*/ 24+0200, /*T*/ 27+0200, /*U*/ 26+0200, /*V*/ 35+0200, /*W*/ 26+0200, /*X*/ 25+0200, /*Y*/ 25+0200, /*Z*/ 16, /*[*/ 0, /*\*/ 16, /*]*/ 0, /*^*/ 0, /*_*/ 10, /*` open*/ 22, /*a*/ 23+0200, /*b*/ 22, /*c*/ 23+0200, /*d*/ 22, /*e*/ 14+0200, /*f*/ 23+0100, /*g*/ 22+0200, /*h*/ 11+0200, /*i*/ 11+0300, /*j*/ 22+0200, /*k*/ 11+0200, /*l*/ 32, /*m*/ 22, /*n*/ 23, /*o*/ 23+0100, /*p*/ 23+0100, /*q*/ 15, /*r*/ 21, /*s*/ 14+0200, /*t*/ 22, /*u*/ 20, /*v*/ 30, /*w*/ 21, /*x*/ 21+0100, /*y*/ 20, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 7, /*narrow space*/ 17, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 32, /*1/4*/ 32, /*1/2*/ 32, /*3/4*/ 27, /*minus*/ 24, /*fi*/ 24, /*fl*/ 28, /*ff*/ 38, /*ffi*/ 38, /*ffl*/ 14, /*degree*/ 23, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 21, /*registered*/ 21, /*copywrite*/ 0, 25, /*cent*/ }; phen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 32, /*1/4*/ 32, /*1/2*/ 32, /*3/4*/ 27, /*minus*/ 24, /*fi*/ 24, /*fl*/ 28, /*ff*/ 38, //*modified for Commercial II*/ char Iw[256-32] { /*Times Italic widths*/ 12, /*space*/ 13, /*!*/ 0, /*"*/ 0, /*#*/ 19, /*$*/ 27, /*%*/ 26, /*&*/ 11, /*' close*/ 15, /*(*/ 15, /*)*/ 16, /***/ 36, /*+*/ 11, /*,*/ 13, /*- hyphen*/ 11, /*.*/ 9, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 20, /*?*/ 0, /*@*/ 25+0200, /*A*/ 24+0200, /*B*/ 26+0200, /*C*/ 27+0200, /*D*/ 23+0200, /*E*/ 21+0200, /*F*/ 27+0200, /*G*/ 29+0200, /*H*/ 14+0200, /*I*/ 16+0200, /*J*/ 28+0200, /*K*/ 24+0200, /*L*/ 34+0200, /*M*/ 27+0200, /*N*/ 27+0200, /*O*/ 22+0200, /*P*/ 27+0300, /*Q*/ 27+0200, /*R*/ 20+0200, /*S*/ 23+0200, /*T*/ 28+0200, /*U*/ 25+0200, /*V*/ 36+0200, /*W*/ 24+0200, /*X*/ 24+0200, /*Y*/ 25+0200, /*Z*/ 13, /*[*/ 0, /*\*/ 13, /*]*/ 0, /*^*/ 0, /*_*/ 11, /*` open*/ 19, /*a*/ 18+0200, /*b*/ 15, /*c*/ 18+0200, /*d*/ 16, /*e*/ 11+0200, /*f*/ 17+0100, /*g*/ 19+0200, /*h*/ 9+0200, /*i*/ 9+0300, /*j*/ 19+0200, /*k*/ 9+0200, /*l*/ 28, /*m*/ 19, /*n*/ 18, /*o*/ 17+0100, /*p*/ 18+0100, /*q*/ 13, /*r*/ 14, /*s*/ 10+0200, /*t*/ 19, /*u*/ 16, /*v*/ 24, /*w*/ 18, /*x*/ 16+0100, /*y*/ 14, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 27, /*1/4*/ 27, /*1/2*/ 27, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 21, /*ff*/ 31, /*ffi*/ 31, /*ffl*/ 15, /*degree*/ 19, /*dagger*/ 0, /*section*/ 7, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 19, /*cent*/ }; phen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 27, /*1/4*/ 27, /*1/2*/ 27, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 21, /*ff*/ 31, /*ffi*/ 31, /*ffl*/ 15char Lw[256-32] { /*L Geneva Light*/ 12, /*space*/ 11, /*!*/ 0, /*"*/ 0, /*#*/ 21, /*$*/ 27, /*%*/ 25, /*&*/ 7, /*' close*/ 13, /*(*/ 13, /*)*/ 16, /***/ 27, /*+*/ 7, /*,*/ 13, /*- hyphen*/ 7, /*.*/ 10, /*/*/ 21+0200, /*0*/ 21+0200, /*1*/ 21+0200, /*2*/ 21+0200, /*3*/ 21+0200, /*4*/ 21+0200, /*5*/ 21+0200, /*6*/ 21+0200, /*7*/ 21+0200, /*8*/ 21+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 22, /*?*/ 0, /*@*/ 23+0200, /*A*/ 24+0200, /*B*/ 26+0200, /*C*/ 26+0200, /*D*/ 22+0200, /*E*/ 20+0200, /*F*/ 27+0200, /*G*/ 26+0200, /*H*/ 10+0200, /*I*/ 18+0200, /*J*/ 24+0200, /*K*/ 20+0200, /*L*/ 30+0200, /*M*/ 26+0200, /*N*/ 28+0200, /*O*/ 22+0200, /*P*/ 28+0300, /*Q*/ 24+0200, /*R*/ 22+0200, /*S*/ 20+0200, /*T*/ 25+0200, /*U*/ 23+0200, /*V*/ 35+0200, /*W*/ 23+0200, /*X*/ 22+0200, /*Y*/ 22+0200, /*Z*/ 11, /*[*/ 0, /*\*/ 11, /*]*/ 0, /*^*/ 0, /*_*/ 7, /*` open*/ 20, /*a*/ 21+0200, /*b*/ 20, /*c*/ 21+0200, /*d*/ 20, /*e*/ 11+0200, /*f*/ 21+0100, /*g*/ 20+0200, /*h*/ 9+0200, /*i*/ 9+0300, /*j*/ 19+0200, /*k*/ 9+0200, /*l*/ 31, /*m*/ 20, /*n*/ 20, /*o*/ 21+0100, /*p*/ 21+0100, /*q*/ 12, /*r*/ 18, /*s*/ 11+0200, /*t*/ 20, /*u*/ 18, /*v*/ 27, /*w*/ 18, /*x*/ 18+0100, /*y*/ 17, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 30, /*1/4*/ 30, /*1/2*/ 30, /*3/4*/ 27, /*minus*/ 20, /*fi*/ 20, /*fl*/ 22, /*ff*/ 31, /*ffi*/ 31, /*ffl*/ 14, /*degree*/ 18, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 21, /*registered*/ 21, /*copywrite*/ 0, 21, /*cent*/ 0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; le*/ 30, /*1/4*/ 30, /*1/2*/ 30, /*3/4*/ 27, /*minus*/ 20, /*fi*/ 20, /*fl*/ 22, /*ff*/ 31, /*ffi*/ 31, /*ffl*/ 14, /*degree*/ 18, /*dagger*/ 0, /*secchar LIw[256-32] { /*LI Geneva Light Italic*/ 12, /*space*/ 12, /*!*/ 0, /*"*/ 0, /*#*/ 21, /*$*/ 27, /*%*/ 26, /*&*/ 7, /*' close*/ 13, /*(*/ 13, /*)*/ 15, /***/ 36, /*+*/ 7, /*,*/ 13, /*- hyphen*/ 7, /*.*/ 7, /*/*/ 21+0200, /*0*/ 21+0200, /*1*/ 21+0200, /*2*/ 21+0200, /*3*/ 21+0200, /*4*/ 21+0200, /*5*/ 21+0200, /*6*/ 21+0200, /*7*/ 21+0200, /*8*/ 21+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 24, /*?*/ 0, /*@*/ 24+0200, /*A*/ 25+0200, /*B*/ 27+0200, /*C*/ 26+0200, /*D*/ 22+0200, /*E*/ 20+0200, /*F*/ 28+0200, /*G*/ 26+0200, /*H*/ 10+0200, /*I*/ 19+0200, /*J*/ 25+0200, /*K*/ 21+0200, /*L*/ 30+0200, /*M*/ 26+0200, /*N*/ 28+0200, /*O*/ 23+0200, /*P*/ 28+0300, /*Q*/ 24+0200, /*R*/ 23+0200, /*S*/ 21+0200, /*T*/ 25+0200, /*U*/ 22+0200, /*V*/ 32+0200, /*W*/ 22+0200, /*X*/ 22+0200, /*Y*/ 22+0200, /*Z*/ 11, /*[*/ 0, /*\*/ 11, /*]*/ 0, /*^*/ 0, /*_*/ 7, /*` open*/ 21, /*a*/ 22+0200, /*b*/ 20, /*c*/ 22+0200, /*d*/ 20, /*e*/ 12+0200, /*f*/ 22+0100, /*g*/ 21+0200, /*h*/ 9+0200, /*i*/ 9+0300, /*j*/ 20+0200, /*k*/ 9+0200, /*l*/ 31, /*m*/ 21, /*n*/ 21, /*o*/ 22+0100, /*p*/ 22+0100, /*q*/ 13, /*r*/ 19, /*s*/ 12+0200, /*t*/ 21, /*u*/ 18, /*v*/ 27, /*w*/ 19, /*x*/ 18+0100, /*y*/ 18, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 27, /*1/4*/ 27, /*1/2*/ 27, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 24, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 21, /*registered*/ 21, /*copywrite*/ 0, 21, /*cent*/ 0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; le*/ 27, /*1/4*/ 27, /*1/2*/ 27, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 24, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 0/*Commercial II*/ char PAw[256-32] { /*character withs for Palatino 814-007A*/ 12, /*space*/ 12, /*!*/ 0, /*"*/ 0, /*sharp*/ 19, /*$*/ 27, /*%*/ 29, /*&*/ 10, /*' close*/ 14, /*(*/ 14, /*)*/ 16, /***/ 27, /*+*/ 9, /*,*/ 14, /*- hyphen*/ 9, /*.*/ 12, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 12, /*:*/ 12, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 20, /*?*/ 0, /*@*/ 28+0200, /*A*/ 21+0200, /*B*/ 25+0200, /*C*/ 28+0200, /*D*/ 21+0200, /*E*/ 20+0200, /*F*/ 27+0200, /*G*/ 30+0200, /*H*/ 12+0200, /*I*/ 12+0200, /*J*/ 27+0200, /*K*/ 22+0200, /*L*/ 34+0200, /*M*/ 30+0200, /*N*/ 29+0200, /*O*/ 22+0200, /*P*/ 29+0300, /*Q*/ 25+0200, /*R*/ 19+0200, /*S*/ 22+0200, /*T*/ 28+0200, /*U*/ 27+0200, /*V*/ 36+0200, /*W*/ 24+0200, /*X*/ 24+0200, /*Y*/ 24+0200, /*Z*/ 13, /*[*/ 0, /*\*/ 13, /*]*/ 0, /*^*/ 0, /*_*/ 10, /*` open*/ 18, /*a*/ 20+0200, /*b*/ 16, /*c*/ 21+0200, /*d*/ 17, /*e*/ 12+0200, /*f*/ 19+0100, /*g*/ 22+0200, /*h*/ 11+0200, /*i*/ 11+0300, /*j*/ 20+0200, /*k*/ 11+0200, /*l*/ 32, /*m*/ 22, /*n*/ 20, /*o*/ 21+0100, /*p*/ 19+0100, /*q*/ 15, /*r*/ 15, /*s*/ 12+0200, /*t*/ 22, /*u*/ 20, /*v*/ 30, /*w*/ 19, /*x*/ 20+0100, /*y*/ 18, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 27, /*1/4*/ 27, /*1/2*/ 27, /*3/4*/ 27, /*minus*/ 22, /*fi*/ 22, /*fl*/ 23, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ 13, /*degree*/ 22, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 19, /*cent*/ }; /4*/ 27, /*1/2*/ 27, /*3/4*/ 27, /*minus*/ 22, /*fi*/ 22, /*fl*/ 23, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ 13, /*degree*/ 22, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0/*Commercial II*/ char W14[256-32] { /*character withs for Palatino Bold 814-009A*/ 12, /*space*/ 14, /*!*/ 00, /*"*/ 00, /*sharp*/ 18, /*$*/ 27, /*%*/ 30, /*&*/ 12, /*' close*/ 14, /*(*/ 14, /*)*/ 15, /***/ 27, /*+*/ 12, /*,*/ 15, /*- hyphen*/ 10, /*.*/ 13, /*/*/ 18+0200, /*0*/ 18+0200, /*1*/ 18+0200, /*2*/ 18+0200, /*3*/ 18+0200, /*4*/ 18+0200, /*5*/ 18+0200, /*6*/ 18+0200, /*7*/ 18+0200, /*8*/ 18+0200, /*9*/ 14, /*:*/ 15, /*;*/ 00, /*<*/ 27, /*=*/ 00, /*>*/ 21, /*?*/ 00, /*@*/ 28+0200, /*A*/ 22+0200, /*B*/ 25+0200, /*C*/ 29+0200, /*D*/ 21+0200, /*E*/ 20+0200, /*F*/ 28+0200, /*G*/ 30+0200, /*H*/ 14+0200, /*I*/ 14+0200, /*J*/ 28+0200, /*K*/ 22+0200, /*L*/ 36+0200, /*M*/ 30+0200, /*N*/ 29+0200, /*O*/ 22+0200, /*P*/ 29+0300, /*Q*/ 26+0200, /*R*/ 20+0200, /*S*/ 25+0200, /*T*/ 28+0200, /*U*/ 28+0200, /*V*/ 36+0200, /*W*/ 25+0200, /*X*/ 25+0200, /*Y*/ 23+0200, /*Z*/ 13, /*[*/ 00, /*\*/ 13, /*]*/ 00, /*^*/ 0, /*_*/ 12, /*` open*/ 18, /*a*/ 20+0200, /*b*/ 16, /*c*/ 22+0200, /*d*/ 18, /*e*/ 14+0200, /*f*/ 20+0100, /*g*/ 22+0200, /*h*/ 12+0200, /*i*/ 12+0300, /*j*/ 22+0200, /*k*/ 12+0200, /*l*/ 32, /*m*/ 22, /*n*/ 20, /*o*/ 22+0100, /*p*/ 20+0100, /*q*/ 15, /*r*/ 16, /*s*/ 13+0200, /*t*/ 22, /*u*/ 21, /*v*/ 31, /*w*/ 19, /*x*/ 21+0100, /*y*/ 18, /*z*/ 00, /*{*/ 2, /*|*/ 00, /*}*/ 00, /*~*/ 6,  /*narrow space*/ 15, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 32, /*1/4*/ 32, /*1/2*/ 32, /*3/4*/ 27, /*minus*/ 23, /*fi*/ 23, /*fl*/ 25, /*ff*/ 34, /*ffi*/ 34, /*ffl*/ 15, /*degree*/ 21, /*dagger*/ 00, /*section*/ 9, /*foot mark*/ 00, /*'*/ 00, /*`*/ 00, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 00, 18, /*cent*/ }; /*1/2*/ 32, /*3/4*/ 27, /*minus*/ 23, /*fi*/ 23, /*fl*/ 25, /*ff*/ 34, /*ffi*/ 34, /*ffl*/ 15, /*degree*/ 21, /*dagger*/ 00, /*section*/ 9, /*foot mark*/ 00, /*'*/ 00, /*`*/ 00, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,/*Commercial II*/ char PIw[256-32] { /*character withs for Palatino Italic 814-008A*/ 12, /*space*/ 9, /*!*/ 00, /*"*/ 00, /*sharp*/ 18, /*$*/ 28, /*%*/ 27, /*&*/ 9, /*' close*/ 13, /*(*/ 13, /*)*/ 19, /***/ 27, /*+*/ 9, /*,*/ 14, /*- hyphen*/ 9, /*.*/ 12, /*/*/ 18+0200, /*0*/ 18+0200, /*1*/ 18+0200, /*2*/ 18+0200, /*3*/ 18+0200, /*4*/ 18+0200, /*5*/ 18+0200, /*6*/ 18+0200, /*7*/ 18+0200, /*8*/ 18+0200, /*9*/ 9, /*:*/ 9,  /*;*/ 00, /*<*/ 27, /*=*/ 00, /*>*/ 14, /*?*/ 00, /*@*/ 27+0200, /*A*/ 21+0200, /*B*/ 24+0200, /*C*/ 27+0200, /*D*/ 20+0200, /*E*/ 18+0200, /*F*/ 26+0200, /*G*/ 27+0200, /*H*/ 12+0200, /*I*/ 12+0200, /*J*/ 25+0200, /*K*/ 20+0200, /*L*/ 36+0200, /*M*/ 28+0200, /*N*/ 27+0200, /*O*/ 20+0200, /*P*/ 27+0300, /*Q*/ 25+0200, /*R*/ 17+0200, /*S*/ 22+0200, /*T*/ 28+0200, /*U*/ 27+0200, /*V*/ 35+0200, /*W*/ 26+0200, /*X*/ 25+0200, /*Y*/ 22+0200, /*Z*/ 14, /*[*/ 00, /*\*/ 14,  /*]*/ 00, /*^*/ 0, /*_*/ 9, /*` open*/ 17, /*a*/ 16+0200, /*b*/ 15, /*c*/ 18+0200, /*d*/ 15, /*e*/ 12+0200, /*f*/ 16+0100, /*g*/ 18+0200, /*h*/ 12+0200, /*i*/ 12+0300, /*j*/ 16+0200, /*k*/ 11+0200, /*l*/ 28, /*m*/ 20, /*n*/ 16, /*o*/ 18+0100, /*p*/ 16+0100, /*q*/ 14, /*r*/ 14, /*s*/ 11+0200, /*t*/ 19, /*u*/ 18, /*v*/ 26, /*w*/ 18, /*x*/ 19+0100, /*y*/ 16, /*z*/ 00, /*{*/ 2, /*|*/ 00, /*}*/ 00, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 28, /*1/4*/ 28, /*1/2*/ 28, /*3/4*/ 27, /*minus*/ 20, /*fi*/ 20, /*fl*/ 20, /*ff*/ 29, /*ffi*/ 29, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 00, /*section*/ 10, /*foot mark*/ 00, /*'*/ 00, /*`*/ 00, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 18, /*cent*/ }; 28, /*1/2*/ 28, /*3/4*/ 27, /*minus*/ 20, /*fi*/ 20, /*fl*/ 20, /*ff*/ 29, /*ffi*/ 29, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 00, /*section*/ 10, /*foot mark*/ 00, /*'*/ 00, /*`*/ 00, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,/*modified for Commercial II*/ char Rw[256-32] { /*Times Roman widths*/ 12, /*space*/ 12, /*!*/ 0, /*"*/ 0, /*#*/ 19, /*$*/ 29, /*%*/ 28, /*&*/ 12, /*' close*/ 16, /*(*/ 16, /*)*/ 16, /***/ 36, /*+*/ 12, /*,*/ 13, /*- hyphen*/ 10, /*.*/ 17, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 10, /*:*/ 12, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 20, /*?*/ 0, /*@*/ 29+0200, /*A*/ 23+0200, /*B*/ 26+0200, /*C*/ 30+0200, /*D*/ 24+0200, /*E*/ 23+0200, /*F*/ 30+0200, /*G*/ 29+0200, /*H*/ 13+0200, /*I*/ 16+0200, /*J*/ 28+0200, /*K*/ 24+0200, /*L*/ 35+0200, /*M*/ 29+0200, /*N*/ 27+0200, /*O*/ 22+0200, /*P*/ 27+0300, /*Q*/ 27+0200, /*R*/ 20+0200, /*S*/ 24+0200, /*T*/ 29+0200, /*U*/ 27+0200, /*V*/ 36+0200, /*W*/ 28+0200, /*X*/ 27+0200, /*Y*/ 23+0200, /*Z*/ 14, /*[*/ 0, /*\*/ 14, /*]*/ 0, /*^*/ 0, /*_*/ 12, /*` open*/ 17, /*a*/ 20+0200, /*b*/ 16, /*c*/ 20+0200, /*d*/ 18, /*e*/ 13+0200, /*f*/ 18+0100, /*g*/ 21+0200, /*h*/ 10+0200, /*i*/ 9+0300, /*j*/ 20+0200, /*k*/ 10+0200, /*l*/ 32, /*m*/ 21, /*n*/ 20, /*o*/ 19+0100, /*p*/ 19+0100, /*q*/ 14, /*r*/ 15, /*s*/ 12+0200, /*t*/ 21, /*u*/ 20, /*v*/ 26, /*w*/ 20, /*x*/ 18+0100, /*y*/ 17, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 29, /*1/4*/ 29, /*1/2*/ 29, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 24, /*ff*/ 32, /*ffi*/ 32, /*ffl*/ 15, /*degree*/ 20, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 19, /*cent*/ }; phen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 29, /*1/4*/ 29, /*1/2*/ 29, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 24, /*ff*/ 32, /*ffi*/ 32, /*ffl*/ /* Modified for Commercial II and with +, -, and = for equations */ char Sw[256-32] { /*Special font widths*/ 0,0, /*.=Sw+042-40*/ 13, /*"*/ 29, /*#*/ 0,0,0,0, /*.=Sw+074-40*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0, 36, /*<*/ 0, /*.=Sw+076-40*/ 36, /*>*/ 0, /*.=Sw+100-40*/ 36, /*@*/ 0,0,0,0,0,0,0, /*.=Sw+134-40*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0, 15, /*\\*/ 0, /*.=Sw+136-40*/ 15, /*^*/ 18, /*_ underrule*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0, 14, /*{*/ 0,  /*.=Sw+175-40*/ 14, /*}*/ 15, /*~*/ 0, /*.=Sw+220-40*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 17, /*section*/ 0, /*.=Sw+222-40*/ 10, /*acute accent*/ 10, /*grave accent*/ 18, /*underrule*/ 15, /*slash (longer)*/ 0, /**/ 0, /**/ 24, /*alpha*/ 23+0300, /*beta*/ 23+0100, /*gamma*/ 19+0200, /*delta*/ 18, /*epsilon*/ 18+0300, /*zeta*/ 23+0100, /*eta*/ 19+0200, /*theta*/ 13, /*iota*/ 21, /*kappa*/ 22+0200, /*lambda*/ 25+0100, /*mu*/ 20, /*nu*/ 20+0300, /*xi*/ 20, /*omicron*/ 27, /*pi*/ 21+0100, /*rho*/ 27, /*sigma*/ 20, /*tau*/ 21, /*upsilon*/ 25+0300, /*phi*/ 22+0100, /*chi*/ 24+0300, /*psi*/ 25, /*omega*/ 24+0200, /*Gamma*/ 26+0200, /*Delta*/ 28+0200, /*Theta*/ 28+0200, /*Lambda*/ 27+0200, /*Xi*/ 29+0200, /*Pi*/ 25+0200, /*Sigma*/ 0, /**/ 28+0200, /*Upsilon*/ 29+0200, /*Phi*/ 32+0200, /*Psi*/ 36+0200, /*Omega*/ 30, /*square root*/ 18+0100, /*terminal sigma*/ 18, /*root en*/ 36, /*>=*/ 36, /*<=*/ 36, /*identically equal*/ 27, /*minus*/ 36, /*approx =*/ 36, /*approximates*/ 36, /*not equal*/ 36, /*right arrow*/ 36, /*left arrow*/ 18, /*up arrow*/ 18, /*down arrow*/ 27, /*equal*/ 27, /*multiply*/ 27, /*divide*/ 36, /*plus-minus*/ 36, /*cup (union)*/ 36, /*cap (intersection)*/ 36, /*subset of*/ 36, /*superset of*/ 36, /*improper subset*/ 36, /*improper superset*/ 34, /*infinity*/ 21, /*partial derivative*/ 36+0200, /*gradient*/ 22, /*not*/ 24, /*integral sign*/ 27, /*proportional to*/ 28, /*empty set*/ 27, /*member of*/ 27, /*plus*/ 0, 0, 0, /*box vert rule (was 2.)*/ 0, 17, /*dbl dagger*/ 42, /*right hand*/ 42, /*left hand*/ 16, /*math * */ 41, /*bell system sign*/ 9, /*or*/ 27, /*circle*/ 9, /*left top (of big curly)*/ 9, /*left bottom*/ 9, /*right top*/ 9, /*right bot*/ 9, /*left center of big curly bracket*/ 9, /*right center of big curly bracket*/ 9, /*bold vertical*/ 9, /*left floor (left bot of big sq bract)*/ 9, /*right floor (rb of ")*/ 9, /*left ceiling (lt of ")*/ 9 }; /*right ceiling (rt of ")*/ /*plus*/ 0, 0, 0, /*box vert rule (was 2.)*/char SBw[256-32] { /*SB Stymie Bold*/ 12, /*space*/ 13, /*!*/ 0, /*"*/ 0, /*#*/ 25, /*$*/ 32, /*%*/ 29, /*&*/ 9, /*' close*/ 15, /*(*/ 15, /*)*/ 13, /***/ 27, /*+*/ 9, /*,*/ 13, /*- hyphen*/ 9, /*.*/ 17, /*/*/ 25+0200, /*0*/ 25+0200, /*1*/ 25+0200, /*2*/ 25+0200, /*3*/ 25+0200, /*4*/ 25+0200, /*5*/ 25+0200, /*6*/ 25+0200, /*7*/ 25+0200, /*8*/ 25+0200, /*9*/ 13, /*:*/ 13, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 25, /*?*/ 0, /*@*/ 30+0200, /*A*/ 26+0200, /*B*/ 27+0200, /*C*/ 28+0200, /*D*/ 25+0200, /*E*/ 24+0200, /*F*/ 28+0200, /*G*/ 30+0200, /*H*/ 14+0200, /*I*/ 17+0200, /*J*/ 29+0200, /*K*/ 23+0200, /*L*/ 35+0200, /*M*/ 30+0200, /*N*/ 29+0200, /*O*/ 24+0200, /*P*/ 29+0300, /*Q*/ 27+0200, /*R*/ 24+0200, /*S*/ 26+0200, /*T*/ 30+0200, /*U*/ 29+0200, /*V*/ 40+0200, /*W*/ 30+0200, /*X*/ 29+0200, /*Y*/ 25+0200, /*Z*/ 13, /*[*/ 0, /*\*/ 13, /*]*/ 0, /*^*/ 0, /*_*/ 9, /*` open*/ 18, /*a*/ 21+0200, /*b*/ 18, /*c*/ 21+0200, /*d*/ 19, /*e*/ 13+0200, /*f*/ 21+0100, /*g*/ 22+0200, /*h*/ 11+0200, /*i*/ 10+0300, /*j*/ 21+0200, /*k*/ 11+0200, /*l*/ 30, /*m*/ 22, /*n*/ 19, /*o*/ 21+0100, /*p*/ 21+0100, /*q*/ 14, /*r*/ 16, /*s*/ 12+0200, /*t*/ 22, /*u*/ 22, /*v*/ 29, /*w*/ 22, /*x*/ 22+0100, /*y*/ 19, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 32, /*1/4*/ 32, /*1/2*/ 32, /*3/4*/ 27, /*minus*/ 24, /*fi*/ 24, /*fl*/ 26, /*ff*/ 37, /*ffi*/ 37, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 0, /*section*/ 10, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copywrite*/ 0, 25, /*cent*/ 0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; e*/ 32, /*1/4*/ 32, /*1/2*/ 32, /*3/4*/ 27, /*minus*/ 24, /*fi*/ 24, /*fl*/ 26, /*ff*/ 37, /*ffi*/ 37, /*ffl*/ 14, /*degree*/ 20, /*dagger*/ 0, /char SIw[256-32] { /*SI Stymie Medium Italic*/ 12, /*space*/ 11, /*!*/ 0, /*"*/ 0, /*#*/ 18, /*$*/ 30, /*%*/ 26, /*&*/ 8, /*' close*/ 12, /*(*/ 12, /*)*/ 17, /***/ 27, /*+*/ 8, /*,*/ 11, /*- hyphen*/ 7, /*.*/ 7, /*/*/ 18+0200, /*0*/ 18+0200, /*1*/ 18+0200, /*2*/ 18+0200, /*3*/ 18+0200, /*4*/ 18+0200, /*5*/ 18+0200, /*6*/ 18+0200, /*7*/ 18+0200, /*8*/ 18+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 22, /*?*/ 0, /*@*/ 25+0200, /*A*/ 23+0200, /*B*/ 24+0200, /*C*/ 25+0200, /*D*/ 24+0200, /*E*/ 23+0200, /*F*/ 26+0200, /*G*/ 27+0200, /*H*/ 11+0200, /*I*/ 11+0200, /*J*/ 25+0200, /*K*/ 21+0200, /*L*/ 30+0200, /*M*/ 27+0200, /*N*/ 26+0200, /*O*/ 21+0200, /*P*/ 26+0300, /*Q*/ 24+0200, /*R*/ 21+0200, /*S*/ 22+0200, /*T*/ 25+0200, /*U*/ 25+0200, /*V*/ 33+0200, /*W*/ 25+0200, /*X*/ 25+0200, /*Y*/ 24+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 8, /*` open*/ 16, /*a*/ 19+0200, /*b*/ 17, /*c*/ 18+0200, /*d*/ 18, /*e*/ 11+0200, /*f*/ 19+0100, /*g*/ 19+0200, /*h*/ 10+0200, /*i*/ 10+0300, /*j*/ 18+0200, /*k*/ 10+0200, /*l*/ 28, /*m*/ 19, /*n*/ 18, /*o*/ 19+0100, /*p*/ 19+0100, /*q*/ 12, /*r*/ 14, /*s*/ 10+0200, /*t*/ 19, /*u*/ 18, /*v*/ 27, /*w*/ 18, /*x*/ 18+0100, /*y*/ 16, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 11, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 29, /*1/4*/ 29, /*1/2*/ 29, /*3/4*/ 27, /*minus*/ 19, /*fi*/ 19, /*fl*/ 20, /*ff*/ 28, /*ffi*/ 28, /*ffl*/ 17, /*degree*/ 19, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 19, /*registered*/ 19, /*copywrite*/ 0, 18, /*cent*/ 0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; le*/ 29, /*1/4*/ 29, /*1/2*/ 29, /*3/4*/ 27, /*minus*/ 19, /*fi*/ 19, /*fl*/ 20, /*ff*/ 28, /*ffi*/ 28, /*ffl*/ 17, /*degree*/ 19, /*daggerchar SMw[256-32] { /*SM Stymie Medium*/ 12, /*space*/ 11, /*!*/ 0, /*"*/ 0, /*#*/ 24, /*$*/ 22, /*%*/ 26, /*&*/ 9, /*' close*/ 13, /*(*/ 13, /*)*/ 13, /***/ 27, /*+*/ 9, /*,*/ 11, /*- hyphen*/ 9, /*.*/ 15, /*/*/ 24+0200, /*0*/ 24+0200, /*1*/ 24+0200, /*2*/ 24+0200, /*3*/ 24+0200, /*4*/ 24+0200, /*5*/ 24+0200, /*6*/ 24+0200, /*7*/ 24+0200, /*8*/ 24+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 22, /*?*/ 0, /*@*/ 27+0200, /*A*/ 22+0200, /*B*/ 25+0200, /*C*/ 25+0200, /*D*/ 20+0200, /*E*/ 20+0200, /*F*/ 27+0200, /*G*/ 27+0200, /*H*/ 12+0200, /*I*/ 14+0200, /*J*/ 25+0200, /*K*/ 20+0200, /*L*/ 30+0200, /*M*/ 26+0200, /*N*/ 27+0200, /*O*/ 20+0200, /*P*/ 27+0300, /*Q*/ 23+0200, /*R*/ 18+0200, /*S*/ 21+0200, /*T*/ 26+0200, /*U*/ 25+0200, /*V*/ 32+0200, /*W*/ 26+0200, /*X*/ 25+0200, /*Y*/ 21+0200, /*Z*/ 14, /*[*/ 0, /*\*/ 14, /*]*/ 0, /*^*/ 0, /*_*/ 9, /*` open*/ 18, /*a*/ 21+0200, /*b*/ 18, /*c*/ 21+0200, /*d*/ 19, /*e*/ 11+0200, /*f*/ 21+0100, /*g*/ 21+0200, /*h*/ 10+0200, /*i*/ 10+0300, /*j*/ 20+0200, /*k*/ 10+0200, /*l*/ 30, /*m*/ 21, /*n*/ 19, /*o*/ 21+0100, /*p*/ 21+0100, /*q*/ 14, /*r*/ 15, /*s*/ 11+0200, /*t*/ 21, /*u*/ 20, /*v*/ 27, /*w*/ 21, /*x*/ 20+0100, /*y*/ 18, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 11, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 31, /*1/4*/ 31, /*1/2*/ 31, /*3/4*/ 27, /*minus*/ 21, /*fi*/ 21, /*fl*/ 22, /*ff*/ 32, /*ffi*/ 32, /*ffl*/ 15, /*degree*/ 19, /*dagger*/ 0,  /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 22, /*registered*/ 22, /*copywrite*/ 0, 24, /*cent*/ 0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0}; le*/ 31, /*1/4*/ 31, /*1/2*/ 31, /*3/4*/ 27, /*minus*/ 21, /*fi*/ 21, /*fl*/ 22, /*ff*/ 32, /*ffi*/ 32, /*ffl*/ 15, /*degree*/ 19, /*dagger*/ 0, /*modified for Commercial II*/ char UDw[256-32] { /*Utica Demibold widths (Utica == Futura)*/ 12, /*space*/ 11, /*!*/ 0, /*"*/ 16, /*0*/ 21, /*$*/ 28, /*%*/ 25, /*&*/ 10, /*' close*/ 14, /*(*/ 14, /*)*/ 13, /***/ 27, /*+*/ 9, /*,*/ 14, /*- hyphen*/ 9, /*.*/ 15, /*/*/ 21+0200, /*0*/ 21+0200, /*1*/ 21+0200, /*2*/ 21+0200, /*3*/ 21+0200, /*4*/ 21+0200, /*5*/ 21+0200, /*6*/ 21+0200, /*7*/ 21+0200, /*8*/ 21+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 27, /*=*/ 0, /*>*/ 20, /*?*/ 0, /*@*/ 24+0200, /*A*/ 19+0200, /*B*/ 22+0200, /*C*/ 21+0200, /*D*/ 19+0200, /*E*/ 16+0200, /*F*/ 26+0200, /*G*/ 24+0200, /*H*/ 12+0200, /*I*/ 17+0200, /*J*/ 21+0200, /*K*/ 14+0200, /*L*/ 29+0200, /*M*/ 26+0200, /*N*/ 26+0200, /*O*/ 19+0200, /*P*/ 27+0300, /*Q*/ 19+0200, /*R*/ 18+0200, /*S*/ 16+0200, /*T*/ 24+0200, /*U*/ 22+0200, /*V*/ 33+0200, /*W*/ 22+0200, /*X*/ 20+0200, /*Y*/ 22+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 10, /*` open*/ 20, /*a*/ 20+0200, /*b*/ 14, /*c*/ 20+0200, /*d*/ 18, /*e*/ 11+0200, /*f*/ 20+0100, /*g*/ 19+0200, /*h*/ 9+0200, /*i*/ 9+0300, /*j*/ 18+0200, /*k*/ 9+0200, /*l*/ 29, /*m*/ 19, /*n*/ 18, /*o*/ 20+0100, /*p*/ 20+0100, /*q*/ 12, /*r*/ 15, /*s*/ 10+0200, /*t*/ 19, /*u*/ 18, /*v*/ 28, /*w*/ 18, /*x*/ 18+0100, /*y*/ 16, /*z*/ 0, /*{*/ 5, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 28, /*1/4*/ 28, /*1/2*/ 28, /*3/4*/ 27, /*minus*/ 18, /*fi*/ 18, /*fl*/ 19, /*ff*/ 27, /*ffi*/ 27, /*ffl*/ 14, /*degree*/ 29, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 16, /*registered*/ 16, /*copywrite*/ 0, 21, /*cent*/ }; phen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 28, /*1/4*/ 28, /*1/2*/ 28, /*3/4*/ 27, /*minus*/ 18, /*fi*/ 18, /*fl*/ 19, /*ff*/ 27, /*signal = 48. testing = 0 / form letter generator / command sequence / form proto arg1 arg2... / where proto is letter rfo: sys signal; 2; int mov $-1,buf mov (sp)+,r2 /arg count tst (sp)+ /skip first arg sub $2,r2 bge 2f mov $default,-(sp) 2: mov (sp)+,letter 1: sys stat; otfil; buf bec 2f sys creat; otfil; 666 bec cont 2: cmpb $'z,otfil+4 beq err3 incb otfil+4 br 1b err3: mov $1,r0 sys write; mes3; 24. sys exit mes3: otfil: default: .even cont: mov r0,rfo clr rfo+2 jsr pc,initl / set up argument list / mov $arg,r3 mov $10.,r0 jsr pc,allocate mov r1,(r3)+ 1: dec r2 blt 1f mov $10.,r0 jsr pc,allocate mov r1,(r3)+ mov (sp)+,r4 2: movb (r4)+,r0 beq 1b jsr pc,putchar br 2b 1: sys time ashc $-7,r0 div $675.,r0 mov $daytab,r2 sub $1461.,r0 1: sub (r2)+,r0 bge 1b add -(r2),r0 mov r0,-(sp) mov arg,r1 mov montab-daytab(r2),r2 1: movb (r2)+,r0 beq 1f jsr pc,putchar br 1b 1: movb $' ,r0 jsr pc,putchar clr r0 mov (sp),r1 inc r1 div $10.,r0 mov r1,(sp) mov arg,r1 tst r0 beq 1f add $'0,r0 jsr pc,putchar 1: mov (sp)+,r0 add $'0,r0 jsr pc,putchar jmp loop daytab: 31.; 28.; 31.; 30.; 31.; 30.; 31.; 31.; 30.; 31.; 30.; 999. montab: m1; m2; m3; m4; m5; m6; m7; m8; m9; m10; m11; m12 m1: m2: m3: m4: m5: m6: m7: m8: m9: m10: m11: m12: buf: .=.+34. .=rfo+516. loop: mov $10.,r0 jsr pc,allocate mov r1,opointer jsr pc,allocate mov r1,ipointer jsr pc,allocate mov r1,curly mov $10.,r0 jsr pc,allocate mov r1,scr mov letter,r3 movb $'\{,r0 jsr pc,putchar 1: movb (r3)+,r0 beq 1f jsr pc,putchar br 1b 1: movb $'\},r0 jsr pc,putchar clr switch tst iflag beq 1f mov $1,tflag jmp interrupt 1: jsr pc,scan movb $'\n,r0 jsr r5,putc jsr r5,flushb mov scr,r1 jsr pc,release jsr pc,relarg mov opointer,r1 jsr pc,release mov ipointer,r1 jsr pc,release jsr pc,relcurl jsr pc,flush jsr pc,whead .if testing 4 .endif sys exit er jsr pc,allocate mov r1,curly mov $10.,r0 jsr pc,allocate mov r1,scr mov letter,r3 movb $'\{,r0 jsr pc,putchar 1: movb (r3)+,r0 beq 1f jsr pc,putchar br 1b 1: movb $'\},r0 jsr pc,putchar clr switch tst iflag beq 1f mov $1,tflag jmp interrupt 1: jsr pc,scan movb $'\n,r0 jsr r5,putc jsr r5,flushb mov scr,r1 jsr pc,release jsr pc,relarg mov opointer,r1 jsr pc,release mov ipointer,r1 jsr pc,release jsr pc,re/ scan / r1 = pointer to input header / r0 = pointer to output header / switch = 0 real output / not 0 output to r0 scan: mov r0,-(sp) mov r1,-(sp) 1: mov (sp),r1 jsr pc,getchar bes 5f cmpb r0,$'\\ beq 3f cmpb r0,$'\[ beq 4f cmpb r0,$'\{ beq 4f cmpb r0,$'\] beq 1f cmpb r0,$'\} beq 7f cmpb r0,$'\n bne 6f jsr pc,lookchar bes 5f movb $'\n,r0 6: tst switch beq 2f mov 2(sp),r1 jsr pc,putchar br 1b 2: jsr r5,putc br 1b 3: jsr pc,getchar br 6b / have [ or { 4: mov r(r1),-(sp) jsr pc,getchar bes 1f cmpb r0,$'0 blt 4f cmpb r0,$'9 bgt 4f jsr pc,getchar cmpb r0,$'\] beq 3f cmpb r0,$'\} beq 3f 4: mov (sp)+,r(r1) mov 2(sp),r0 jsr pc,esub mov r1,(sp) mov r0,2(sp) br 1b / have arg 3: tst switch beq 2f mov opointer,r1 mov 4(sp),r0 jsr pc,putword mov 2(sp),r1 2: mov (sp)+,r(r1) jsr pc,getchar inc r(r1) /skip ] jsr pc,earg br 1b 5: tst argf bne 1f mov ipointer,r1 jsr pc,pop bes 1f mov r0,(sp) br 1b 7: inc curlyf 1: mov (sp)+,r1 mov (sp)+,r0 rts pc jsr / esub / r1 = pointer to input string / esub: mov r1,-(sp) tst switch beq 1f mov opointer,r1 jsr pc,putword 1: tst iflag beq 1f mov $2,tflag jmp interrupt 1: inc switch mov $10.,r0 jsr pc,allocate mov r1,r0 mov opointer,r1 jsr pc,putword mov (sp)+,r1 jsr pc,scan tst iflag beq 1f mov $3,tflag jmp interrupt 1: mov r2,-(sp) mov r1,r0 mov ipointer,r1 jsr pc,putword mov opointer,r1 jsr pc,pop bec 9f; 4; 9: mov r0,-(sp) /last output mov asmem,r1 jsr pc,getsp bes 2f 5: clr curlyf  mov (sp),r1 mov r0,r2 jsr pc,release 6: mov opointer,r1 jsr pc,pop bec 4f clr switch 4: mov r2,r1 jsr pc,rewind tst (sp)+ mov (sp)+,r2 rts pc / not in memory 2: mov curly,r1 jsr pc,getsp bes 2f br 5b 2: mov (sp),r1 jsr pc,rewind mov $'\[,r0 1: jsr r5,tfoput jsr pc,getchar bec 1b mov $'\],r0 jsr r5,tfoput mov $10.,r0 jsr pc,allocate mov r1,r2 mov (sp),r0 tst curlyf beq 1f clr curlyf mov curly,r1 jsr pc,addentry br 2f 1: mov asmem,r1 jsr pc,whead jsr pc,addentry 2: mov r2,r1 jsr pc,accept br 6b / / / earg / r0 = number in ascii / earg: tst iflag beq 1f mov $4,tflag jmp interrupt 1: mov r1,-(sp) inc argf sub $'0,r0 asl r0 mov arg(r0),r1 beq 5f 4: mov (sp),r0 mov r1,(sp) mov ipointer,r1 jsr pc,putword mov opointer,r1 jsr pc,pop bec 3f clr switch 3: mov (sp)+,r1 jsr pc,rewind jsr pc,scan mov r0,-(sp) mov ipointer,r1 jsr pc,pop bec 9f; 4; 9: mov r0,r1 clr argf clr curlyf mov (sp)+,r0 rts pc 5: mov r0,-(sp) mov $'\[,r0 jsr r5,tfoput mov (sp),r0 asr r0 add $'0,r0 jsr r5,tfoput mov $'\],r0 jsr r5,tfoput mov $10.,r0 jsr pc,allocate mov (sp)+,r0 mov r1,arg(r0) jsr pc,accept br 4b $'0,r0 asl r0 mov arg(r0),r1 beq 5f 4: mov (sp),r0 mov r1,(sp) mov ipointer,r1 jsr pc,putword mov opointer,r1 jsr pc,pop bec 3f clr switch 3: mov (sp)+,r1 jsr pc,rewind jsr pc,scan mov r0,-(sp) mov ipointer,r1 jsr pc,pop bec 9f; 4; 9: mov r0,r1 clr argf clr curlyf mov (sp)+,r0 rts pc 5: mov r0,-(sp) mov $'\[,r0 jsr r5,tfoput mov (sp),rti = 2 / accept / r1 = header of where to put it / accept: mov r0,-(sp) movb $':,r0 jsr r5,tfoput movb $' ,r0 jsr r5,tfoput 2: jsr r5,tfiget cmpb r0,$'\n beq 1f jsr pc,putchar br 2b 1: jsr pc,putchar jsr r5,tfiget cmpb r0,$'\n beq 1f jsr pc,putchar br 2b 1: mov (sp)+,r0 rts pc / / / routine to get the last word from the string / r1=header addr / pop: jsr pc,fsfile jsr pc,backword bes 1f sub $2,w(r1) 1: rts pc / / / routine to add an entry to assoc mem or curly / r1 = header / r0 = header of string name / r2 = header of string / addentry: jsr pc,putword mov r2,r0 jsr pc,putword rts pc / / / routine to find the string pointed to by r0 / in either memory or curly / r1 = where to look / / returns error set if string not there / returns r1 = header of string if there / getsp: mov r0,-(sp) mov r1,-(sp) jsr pc,rewind /memory 3: mov 2(sp),r1 jsr pc,rewind /output mov (sp),r1 jsr pc,getword bes 1f mov r0,r1 mov r0,-(sp) jsr pc,rewind /string 2: mov (sp),r1 jsr pc,getchar bes 2f movb r0,r2 mov 4(sp),r1 jsr pc,getchar bes 4f cmpb r0,r2 beq 2b 4: tst (sp)+ 4: mov (sp),r1 add $2,r(r1) br 3b 2: tst (sp)+ mov 2(sp),r1 cmp r(r1),w(r1) bne 4b mov (sp)+,r1 jsr pc,getword tst (sp)+ rts pc 1: mov (sp)+,r1 mov (sp)+,r0 sec rts pc / / / tfoput / / jsr r5,tfoput / tfoput: mov r0,ch mov $1,r0 sys write; ch; 1 rts r5 / / / tfiget / / jsr r5,tfiget / tfiget: clr r0 sys read; ch; 1 bes 1f tst r0 beq 1f movb ch,r0 rts r5 1: jsr r5,flushb tst argf beq 1f mov opointer,r1 jsr pc,pop 1: mov $5,tflag jmp interrupt / / putc / jsr r5,putc / putc: mov r1,-(sp) mov r2,-(sp) mov $rfo+2,r1 mov r1,r2 add (r1),r2 movb r0,2(r2) inc (r1) cmp (r1),$512. bge 1f mov (sp)+,r2 mov (sp)+,r1 rts r5 1: mov (sp)+,r2 mov (sp)+,r1 / / / flush output buffer to output file. / flushb: mov r1,-(sp) mov r0,-(sp) mov $rfo,r1 mov (r1)+,r0 mov (r1),0f+2 beq 1f clr (r1)+ mov r1,0f sys write; 0:..;.. 1: mov (sp)+,r0 mov (sp)+,r1 rts r5 relarg: mov $arg,r2 1: mov (r2)+,r1 beq 2f jsr pc,release br 1b 2: cmp r2,$arge blt 1b rts pc / relcurl: mov curly,r1 jsr pc,rewind 1: jsr pc,getword bes 1f mov r0,r1 jsr pc,release mov curly,r1 br 1b 1: jsr pc,release rts pc / int: inc iflag rti / interrupt: jsr pc,relarg tst opointer beq 2f 1: mov opointer,r1 jsr pc,rewind 1: jsr pc,getword bes 1f mov r0,r1 jsr pc,release mov opointer,r1 br 1b 1: mov opointer,r1 jsr pc,release tst ipointer beq 2f mov ipointer,r1 jsr pc,release tst curly beq 2f jsr pc,relcurl tst scr beq 2f mov scr,r1 jsr pc,release 2: jsr pc,flush jsr pc,whead sys exit letter: .=.+2 arg: .=.+20. arge: 0 argf: .=.+2 switch: .=.+2 curly: .=.+2 curlyf: .=.+2 ch: .=.+2 opointer: .=.+2 ipointer: .=.+2 scr: .=.+2 iflag: 0 tflag: 0 end: tst opointer beq 2f 1: mov opointer,r1 jsr pc,rewind 1: jsr pc,getword bes 1f mov r0,r1 jsr pc,release mov opointer,r1 br 1b 1: mov opointer,r1 jsr pc,release tst ipointer beq 2f mov ipointer,r1 jsr pc,release tst curly beq 2f jsr p.globl b1 .globl hblk .globl headers .globl initl .globl asmem .globl b1s .globl b1e .globl w1 .globl stats .globl lookchar .globl flush .globl fsfile .globl seekchar .globl backspace .globl alterchar .globl zero .globl getchar .globl putchar .globl copy .globl rewind .globl create .globl allocate .globl release .globl collect .globl w,r,a,l .globl getword .globl putword .globl backword .globl alterword / / / routine to read next character from string / pointer to by r1; character returned in r0 / c-bit set if character not availiable (eof) / / mov ...,r1 / jsr pc,getchar / movb r0,... / getchar: jsr pc,lookchar bes 1f inc r(r1) tst r0 /clears c-bit 1: rts pc / / / routine to read a string backwards / the read pointer is decremented before reading / / mov ...,r1 / jsr pc,backspace / mov r0,... / backspace: cmp a(r1),r(r1) bhis nochc dec r(r1) jsr pc,lookchar rts pc nochc: clr r0 sec rts pc / / / routine to put a word onto the string / / mov ...,r1 / mov ...,r0 / jsr pc,putword / putword: mov r0,-(sp) sub $hblk,r0 jsr pc,putchar swab r0 jsr pc,putchar mov (sp)+,r0 rts pc / / / routine to get a word from the string / / mov ...,r1 / jsr pc,getword / mov r0,... / getword: jsr pc,lookchar bes 1f movb r0,nchar inc r(r1) jsr pc,lookchar bes 1f movb r0,nchar+1 inc r(r1) mov nchar,r0 add $hblk,r0 1: rts pc / / / routine to alter the word pointed to by r(r1) / by replacing the word there with r0 / / mov wd,r0 / mov ...,r1 / jsr pc,alterword / alterword: mov r0,-(sp) sub $hblk,r0 jsr pc,alterchar swab r0 jsr pc,alterchar mov (sp)+,r0 rts pc / / / routine to get words backwards from string / / mov ...,r1 / jsr pc,backword / mov r0,... / backword: cmp a(r1),r(r1) bhis nochw dec r(r1) jsr pc,lookchar movb r0,nchar+1 cmp a(r1),r(r1) bhis nochw dec r(r1) jsr pc,lookchar movb r0,nchar mov nchar,r0 add $hblk,r0 rts pc / nochw: clr r0 sec rts pc / / / routine to copy the contents of one string / to another. / / mov source,r0 / mov dest,r1 / jsr pc,copy / mov r1,... / / on return, r1 points to the new string and should / be saved. r0 is preserved. / copy: inc stats+12. mov r0,-(sp) mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov w(r0),r2 sub a(r0),r2 /W-A (old) mov l(r1),r3 sub a(r1),r3 /L-A (new) cmp r2,r3 blos 1f mov r2,r0 jsr pc,allocate mov 4(sp),r0 /new jsr pc,swap jsr pc,release mov r0,r1 mov 0(sp),r0 /old 1: mov a(r1),w(r1) /rewind w pointer cmp r2,$512. blos copy1 /is a short string / jsr pc,flush jsr pc,reset / mov a(r0),-(sp) 4: mov (sp),0f mov afi,r0 sys seek;0:.. ;0 /set input pointer cmp r2,$512. blos 2f mov $512.,r3 /# output this time mov r3,0f mov r3,3f add r3,(sp) sub r3,r2 /# left to output br 1f 2: mov r2,0f mov r2,3f mov r2,r3 clr r2 1: mov afi,r0 sys read;b1;0:.. bes bad cmp r0,r3 bne bad mov afout,r0 mov (r1),0f add r3,(r1) sys seek;0:.. ;0 sys write;b1;3:.. bes bad tst r2 bgt 4b tst (sp)+ / / fix up read ptr of new string / copy2: mov 6(sp),r0 /restore r0 mov r(r0),r2 sub a(r0),r2 add a(r1),r2 mov r2,r(r1) / / restore and return / mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rts pc / bad: mov $1,r0 sys write;1f;2f-1f 4 1: 2: .even / swap: mov w(r1),-(sp) mov w(r0),w(r1) mov (sp),w(r0) mov r(r1),(sp) mov r(r0),r(r1) mov (sp),r(r0) mov a(r1),(sp) mov a(r0),a(r1) mov (sp),a(r0) mov l(r1),(sp) mov l(r0),l(r1) mov (sp)+,l(r0) rts pc / / copy a short string / copy1: mov r(r0),-(sp) mov a(r0),r(r0) mov nchar,-(sp) mov r0,r2 /old mov r1,r3 /new 1: mov r2,r1 jsr pc,getchar bes 1f mov r3,r1 jsr pc,putchar br 1b 1: mov r2,r0 mov (sp)+,nchar mov (sp)+,r(r0) mov r3,r1 br copy2 / / / / / / routine to rewind read pointer of string / pointed to by r1 / / mov ...,r1 / jsr pc,rewind / rewind: mov a(r1),r(r1) rts pc / / / routine to rewind write pointer of string / pointed to by r1 / / mov ...,r1 / jsr pc,create / create: mov a(r1),w(r1) mov a(r1),r(r1) rts pc / / / routine to zero a string / / mov ...,r1 / jsr pc,zero / zero: mov r0,-(sp) .if testing jsr pc,preposterous .endif mov a(r1),w(r1) clrb r0 1: cmp w(r1),l(r1) bhis 1f jsr pc,putchar br 1b 1: mov a(r1),w(r1) mov (sp)+,r0 rts pc / / / / routine to move the read pointer of a string to the / relative position indicated by r0. the string is / extended if necessary - there is no error return. / / mov position,r0 / mov ...,r1 / jsr pc,seekchar / seekchar: mov r1,-(sp) mov r0,-(sp) .if testing jsr pc,preposterous .endif inc stats+10. 1: mov (sp),r0 add a(r1),r0 cmp r0,l(r1) bhi 3f mov r0,r(r1) cmp r0,w(r1) blo 1f mov r0,w(r1) br 1f 3: mov (sp),r0 jsr pc,allocate mov 2(sp),r0 jsr pc,copy jsr pc,swap jsr pc,release mov 2(sp),r1 br 1b 1: mov (sp)+,r0 mov (sp)+,r1 rts pc / / / routine to move read pointer of string to end of string / / mov ...,r1 / jsr pc,fsfile / fsfile: mov r0,-(sp) .if testing jsr pc,preposterous .endif inc stats+10. mov w(r1),r(r1) mov (sp)+,r0 rts pc / / / routine to place the character in r0 at the current / position of the read pointer - the read pointer / is not moved. / / movb ch,r0 / mov ...,r1 / jsr pc,alterchar / mov r1,... / alterchar: mov r2,-(sp) mov r1,-(sp) mov r0,nchar .if testing jsr pc,preposterous .endif inc stats+8. 1: cmp r(r1),l(r1) /W,L blo 3f mov l(r1),r0 inc r0 sub a(r1),r0 /W-A+1 jsr pc,allocate mov (sp),r0 jsr pc,copy jsr pc,swap jsr pc,release mov (sp),r1 3: mov r(r1),r0 jsr pc,bufchar bec 2f jsr pc,getbuf 2: movb nchar,(r0) mov $1,w1(r2) mov nchar,r0 /to preserve r0 for user inc r(r1) cmp r(r1),w(r1) blos 3f mov r(r1),w(r1) 3: mov (sp)+,r1 mov (sp)+,r2 rts pc / / / routine to look at next character from string / pointed to by r1; character returned in r0 / c-bit set if character not available (end of file) / r1 is preserved / / mov ...,r1 / jsr pc,lookchar / movb r0,... / lookchar: mov r2,-(sp) inc stats+6. .if testing jsr pc,preposterous .endif cmp w(r1),r(r1) /W,R blos noch mov r(r1),r0 jsr pc,bufchar bec 2f jsr pc,getbuf / 2: inc flag bne 2f jsr pc,fixct br 1f 2: mov flag,u1(r2) 1: mov (sp)+,r2 movb (r0),r0 tst r0 /clears c-bit rts pc / noch: mov (sp)+,r2 clr r0 sec rts pc / / / routine to put a character into the string / pointed to by r1; character in r0 / r0 is preserved; r1 points to the string / after return and must be saved. / / movb ch,r0 / mov ...,r1 / jsr pc,putchar / mov r1,... / putchar: mov r2,-(sp) mov r1,-(sp) mov r0,nchar .if testing jsr pc,preposterous .endif inc stats+8. 1: cmp w(r1),l(r1) /W,L blo 3f mov w(r1),r0 inc r0 sub a(r1),r0 /W-A+1 jsr pc,allocate mov (sp),r0 jsr pc,copy jsr pc,swap jsr pc,release mov (sp),r1 3: mov w(r1),r0 jsr pc,bufchar bec 2f jsr pc,getbuf 2: movb nchar,(r0) mov $1,w1(r2) mov nchar,r0 /to preserve r0 for user inc w(r1) inc flag bne 2f jsr pc,fixct br 1f 2: mov flag,u1(r2) 1: mov (sp)+,r1 mov (sp)+,r2 rts pc / / / routine to flush contents of all buffers. / / jsr pc,flush / flush: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) clr r3 1: cmp r3,$numb bhis 1f mov r3,r2 asl r2 tst w1(r2) ble 2f mov r3,r1 ashc $9.,r1 bic $777,r1 add $b1,r1 jsr pc,clean 2: inc r3 br 1b 1: mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 rts pc / / reset: mov r3,-(sp) mov r2,-(sp) clr r3 1: cmp r3,$numb bge 1f mov r3,r2 asl r2 mov $-1.,w1(r2) clr b1s(r2) clr b1e(r2) clr u1(r2) inc r3 br 1b 1: clr flag mov (sp)+,r2 mov (sp)+,r3 rts pc / / / routine to read from disc to a buffer / wcing the buffer if necessary / / mov disc addr,r0 / mov buffer addr,r2 / jsr pc,getb / / on return r0 = addr of byte in buffer / getb: mov r3,-(sp) mov r1,-(sp) mov r0,-(sp) mov r2,r3 asr r3 mov r3,r1 ashc $9.,r1 bic $777,r1 add $b1,r1 tst w1(r2) / w ble 1f jsr pc,clean 1: mov (sp),r0 bic $777,r0 /get lowest multiple of 512. mov r0,0f mov r0,b1s(r2) /set start mov afi,r0 sys seek;0:..;0 mov r1,0f sys read;0:..;512. mov b1s(r2),b1e(r2) add $512.,b1e(r2) / set end clr w1(r2) /clear w mov (sp)+,r0 sub b1s(r2),r0 add r1,r0 / set r0=byte addr in buffer mov (sp)+,r1 mov (sp)+,r3 rts pc / / / routine to wc a buffer / / mov buffer addr,r2 / mov buffer addr+6,r1 beginning of buffer / jsr pc,clean / clean: inc stats+24. mov r0,-(sp) mov b1s(r2),0f mov afout,r0 sys seek;0:..;0 mov r1,0f sys write;0:..;512. clr w1(r2) /clear w mov (sp)+,r0 rts pc / / / routine to get buffer addr of byte whose disc / addr is in r0 - also returns addr of write / flag for buffer in r2 / / mov disc addr,r0 / jsr pc,bufchar / mov (r0),r0 for read / inc (r2) for write must inc w / / c-bit set if char not in either buffer / bufchar: mov r1,-(sp) mov r3,-(sp) clr r3 1: mov r3,r2 asl r2 cmp r0,b1s(r2) blo 2f cmp r0,b1e(r2) bhis 2f sub b1s(r2),r0 mov r3,r1 ashc $9.,r1 bic $777,r1 add r1,r0 add $b1,r0 mov (sp)+,r3 mov (sp)+,r1 clc rts pc 2: inc r3 cmp r3,$numb blt 1b mov (sp)+,r3 mov (sp)+,r1 sec rts pc / / / routine to get a buffer / / mov disc addr,r0 / jsr pc,getbuf / mov (r0),r0 (for read) / inc (r2) must inc w for w / getbuf: mov r4,-(sp) mov r3,-(sp) mov $2,r3 clr r2 mov $1,r4 1: cmp r4,$numb bge 1f cmp u1(r3),u1(r2) bhis 2f mov r3,r2 2: inc r4 add $2.,r3 br 1b 1: mov r2,r3 jsr pc,getb add $stats+14.,r3 inc (r3) mov (sp)+,r3 mov (sp)+,r4 rts pc / / / this routine renumbers the time used cell u1(r2) / of the buffers when the clock overflows / fixct: mov r1,-(sp) mov r3,-(sp) mov $numb,r1 mov $numb,flag 2: mov r1,u1(r2) dec r1 bge 1f mov (sp)+,r3 mov (sp)+,r1 rts pc 1: clr r2 mov $2,r3 1: cmp r3,$numb2 bge 2b cmp u1(r3),u1(r2) blo 2f mov r3,r2 2: add $2,r3 br 1b b bge 1f cmp u1(r3),u1(r2) bhis 2f mov r3,r2 2: inc r4 add $2.,r3 br 1b 1: mov r2,r3 jsr pc,getb add $stats+14.,r3 inc (r3) mov (sp)+,r3 mov (sp)+,r4 rts pc / / / this routine renumbers the time used cell u1(r2) / of the buffers when the clock overflows / fixct: mov r1,-(sp) mov r3,-(sp) mov $numb,r1 mov $numb,flag 2: mov r1,u1(r2) dec r1 bge 1f mov (sp)+,r3 mov (sp)+,r1 rts pc 1: clr r2 mov $2,r3 1: cmp r3,$numb2 bge 2b cmp u1(r3),u1(r2) blo 2f mov r3,r2 2: add $2,r3 br 1b.globl b1 .globl log2 .globl frlist .globl stats .globl b1s .globl b1e .globl w1 / here to allocate a new block / / / mov ...,r0 / jsr pc,allocate / mov r1,... / / requested size in bytes in r0 / pointer to header of allocated block returned in r1 / r0 is preserved / / convert to words, adjust for header, round up / to a power of two / / each block has a four-word header / W - write ptr (also used as link ptr in frlist) / R - read ptr / A - pointer to head of data / L - ptr to (end+1) of data hsz=6144. datasz = 32768. numb=4. numb2=2*numb w=0 r=2 a=4 l=6 / allocate: clr garbage mov r0,-(sp) mov r2,-(sp) mov r3,-(sp) inc stats bne 9f; inc stats; 9: cmp r0,$datasz blo 9f; 4; 9: dec r0 bmi 1f jsr pc,log2 inc r0 1: asl r0 mov r0,-(sp) add $2,r0 cmp r0,$frend-frlist+2 blo zzz 4 / / look on free list for block of required size / zzz: mov (sp),r0 tst frlist(r0) beq xxx / / found it, allocate and return / mov frlist(r0),r1 add $hblk,r1 mov (r1),frlist(r0) mov a(r1),r0 mov r0,w(r1) /W mov r0,r(r1) /R tst (sp)+ mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r0 / jsr pc,whead rts pc / / no block of required size / look for larger block / xxx: tst hblk beq www tst (r0)+ cmp r0,$frend-frlist bhis www tst frlist(r0) bne yyy br xxx / / there are no larger blocks; must garbage collect / www: jsr pc,collect tst r0 bne zzz / / out of space / mov $1,r0 sys write; 1f; 2f-1f jmp interrupt 1: 2: .even / / split larger block into two smaller pieces and / link together as smaller blocks in the free list. / yyy: mov hblk,r3 /get free header block beq www /should never get this mov frlist(r0),r1 add $hblk,r1 mov w(r1),frlist(r0) mov r3,w(r1) add $hblk,r3 mov exp2-2(r0),r2 add a(r1),r2 mov w(r3),hblk mov l(r1),l(r3) mov r2,l(r1) /L mov r2,a(r3) clr w(r3) /W' mov r1,r2 sub $hblk,r2 mov r2,frlist-2(r0) br zzz / / / here to release a block / / mov ...,r1 / jsr pc,release / / pointer to block in r1 / release: / / discover that this is a plausible pointer / mov r0,-(sp) jsr pc,preposterous / / find free list index and link block to that entry / inc stats+2 mov frlist(r0),w(r1) clr r(r1) sub $hblk,r1 mov r1,frlist(r0) clr r1 /self-defense mov (sp)+,r0 rts pc / / / jsr pc,collect / / coalesce free storage by rejoining paired blocks / on the free list. / zero is returned in r0 if no paired blocks were found. / collect: mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) clr useful inc stats+4. clr r0 /start with smallest blocks /r0 contains frlist index loop1: mov $frlist,r1 add r0,r1 / / try next list member at this level / loop2: mov (r1),r3 beq advance /list is empty add $hblk,r3 tst (r3) /W beq advance /only one list element / / calculate address of buddy / mov a(r3),r4 sub $hsz,r4 mov exp2(r0),r2 xor r2,r4 1: add $hsz,r4 / / and search for him / loop3: cmp a(r3),r4 beq coal mov r3,r2 mov w(r3),r3 tst r3 beq nocoal add $hblk,r3 br loop3 / / have found a pair; remove both blocks from list, / coalesce them, and put them on next higher list / coal: mov $1,useful mov w(r3),w(r2) /remove him from list mov (r1),r2 add $hblk,r2 mov r3,r4 mov w(r2),w(r1) /remove other one cmp a(r2),a(r4) bhi 1f mov r2,-(sp) mov r4,r2 mov (sp)+,r4 1: mov hblk,(r2) clr r(r2) mov $hsz,a(r2) mov $hsz,l(r2) sub $hblk,r2 mov r2,hblk add exp2(r0),l(r4) /L clr r(r4) mov frlist+2(r0),w(r4) sub $hblk,r4 mov r4,frlist+2(r0) br loop2 / / no buddy found, try next block on this list / nocoal: mov (r1),r1 add $hblk,r1 br loop2 / / advance to next free list / advance: tst (r0)+ cmp r0,$frend-frlist blo loop1 mov useful,r0 / / do we have enough headers to continue? / tst garbage beq 1f mov $1,r0 sys write; 4f; 5f-4f 4 / 4: 5: .even / / / restore registers and return / 1: inc garbage mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 rts pc / garbage:.=.+2 / / routine to find integer part of log2(x) / / jsr pc,log2 / / r0 = log2(r0) / log2: mov $15.,-(sp) tst r0 bne 1f clr (sp) br 2f 1: asl r0 bcs 2f dec (sp) br 1b 2: mov (sp)+,r0 rts pc / 0 exp2: 1;2;4;10;20;40;100;200;400;1000;2000;4000; 10000;20000;40000;100000 / / routine to discover whether r1 points to / a plausible header - to avoid ruination. / / r1 is preserved and r0 gets a suitable index for frlist / / jsr pc,preposterous / preposterous: cmp r1,$headers bhis 9f; 4; 9: cmp r1,$headend blo 9f; 4; 9: cmp a(r1),$hsz /A bhis 9f; 4; 9: cmp l(r1),$hsz+datasz /L blos 9f; 4; 9: mov l(r1),r0 /L sub a(r1),r0 /A mov r0,-(sp) jsr pc,log2 asl r0 cmp exp2(r0),(sp) beq 9f; 4; 9: add $2,r0 cmp r0,$frend-frlist+2 blo 9f; 4; 9: sub $2,r0 mov r0,(sp) mov frlist(r0),r0 1: beq 1f add $hblk,r0 cmp r0,r1 bne 9f; 4; 9: mov (r0),r0 br 1b 1: mov (sp)+,r0 rts pc / / / whead: inc stats+22. mov r0,-(sp) mov afout,r0 sys seek; 0; 0 sys write; hblk; hsz mov (sp)+,r0 rts pc / / initl: clr hblk mov r0,-(sp) mov r2,-(sp) sys open;almem; 1 /open for write bec 2f sys creat;almem; 666 bes err2 inc hblk 2: mov r0,afout sys open; almem; 0 /open for read bes err2 mov r0,afi br 1f / err2: mov $1,r0 sys write; 4f; 5f-4f 4 .data 4: 5: almem: .even .text / 1: tst hblk bgt 1f sys read; hblk; hsz /r0 already afi mov asmdisc,asmem add $hblk,asmem br 2f 1: mov $headers,r2 mov r2,r0 sub $hblk,r0 mov r0,hblk 1: add $8,r0 mov r0,(r2) add $8,r2 cmp r2,$headend-8. blo 1b clr -8(r2) mov $frlist,r0 1: clr (r0)+ cmp r0,$frend blo 1b mov hblk,r2 add $hblk,r2 mov (r2),hblk clr w(r2) mov $hsz,a(r2) mov $hsz+datasz,l(r2) mov $datasz,r0 jsr pc,log2 asl r0 cmp r0,$frend-frlist blo 9f; 4; 9: sub $hblk,r2 mov r2,frlist(r0) / / install plausible pointers to make octal dumps look nice / mov $hblk,r1 1: mov (r1),r1 tst r1 beq 1f add $hblk,r1 mov $hsz,a(r1) mov $hsz,l(r1) mov $hsz,r(r1) br 1b 1: mov afout,r0 sys write;hblk;hsz jsr pc,reset mov $4,r0 jsr pc,allocate mov r1,asmem mov r1,asmdisc sub $hblk,asmdisc 2: mov (sp)+,r2 mov (sp)+,r0 rts pc / / .bss / b1s: .=.+numb2 b1e: .=.+numb2 w1: .=.+numb2 u1: .=.+numb2 b1: .=. + [512.*numb] flag: .=.+2 stats: .=.+24. /alloc/release/collect/get/put/seek/copy useful: .=.+2 afi: .=.+2 afout: .=.+2 asmem: .=.+2 nchar: .=.+2 / / hblk: .=.+2 /must remain here - pointer to free header frlist: .=hblk+34. frend: asmdisc:.=.+2 headers: .=hblk+hsz headend: .text 0 sys write;hblk;hsz jsr pc,reset mov $4,r0 jsr pc,allocate mov r1,asmem mov r1,asmdisc sub $hblk,asmdisc 2: mov (sp)+,r2 mov (sp)+,r0 rts pc / / .bss / b1s: .=.+numb2/ fakefp -- fake floating point simulator .globl fptrap fptrap: sub $2,(sp) mov r0,-(sp) sys signal; 4; 0 mov (sp)+,r0 2 / rti useful: .=.+2 afi: .=.+2 afout: .=.+2 asmem: .=.+2 nchar: .=.+2 / / hblk: .=.+2 /must remain here - pointer to free header frlist: .=hblk+34. frend: asmdisc:.=.+2 headers: .=hblk+hsz headend: .text 0 sys write;hblk;hsz jsr pc,reset mov $4,r0 jsr pc,allocate mov r1,asmem mov r1,asmdisc sub $hblk,asmdisc 2: mov (sp)+,r2 mov (sp)+,r0 rts pc / / .bss / b1s: .=.+numb2/ fp1 -- floating point simulator rti = 2 bpt = 3 m.ext = 200 / long mode bit m.lngi = 100 / long integer mode .globl fptrap .globl ac0, ac1, ac2, ac3 fptrap: dec reenter bge 1f 4 / reentered! 1: mov (sp)+,spc mov (sp)+,sps mov r0,sr0 sys signal;4;fptrap mov $sr1,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ sub $8,sp / room for double push mov (r0),r5 / pc clr trapins mov -(r5),r5 / trapped instruction mov r5,r4 bic $7777,r4 cmp r4,$170000 beq 1f jmp badins 1: bic $100000,fpsr / clear fp error bic $170000,r5 mov r5,r4 bit $7000,r4 bne class3 bit $700,r4 bne class2 cmp r4,$12 blos 1f jmp badins 1: asl r4 jmp *1f(r4) .data 1: i.cfcc / 170000 i.setf / 170001 i.seti / 170002 badins badins badins badins badins badins i.setd / 170011 i.setl / 170012 .text class2: cmp r5,$400 bge 1f jsr r1,fsrc; mod0rx; mod242 br 2f 1: jsr r1,fsrc; mod0f; mod24f 2: mov r3,r5 asl r4 asl r4 clrb r4 swab r4 asl r4 jsr pc,*1f(r4) jmp sret .data 1: badins / 1700xx i.ldfps / 1701xx i.stfps / 1702xx badins / 1703xx - stst i.clrx / 1704xx i.tstx / 1705xx i.absx / 1706xx i.negx / 1707xx .text class3: cmp r5,$5000 blt 1f mov r5,r2 clrb r2 cmp r2,$6400 blt 2f sub $1400,r2 2: cmp r2,$5000 bne 2f jsr r1,fsrc; mod0rx; mod242 br 3f 2: cmp r2,$5400 bne 2f jsr r1,fsrc; mod0ra; mod24i br 3f 2: jsr r1,fsrc; mod0f; mod24d br 3f 1: jsr r1,fsrc; mod0f; mod24f 3: jsr pc,freg mov r2,r5 clrb r4 swab r4 asl r4 jsr pc,*1f(r4) br sret .data 1: badins / 1700xx badins / 1704xx i.mulx / 1710xx i.modx / 1714xx i.addx / 1720xx i.ldx / 1724xx i.subx / 1730xx i.cmpx / 1734xx i.stx / 1740xx i.divx / 1744xx i.stexp / 1750xx i.stcxj / 1754xx i.stcxy / 1760xx i.ldexp / 1764xx i.ldcjx / 1770xx i.ldcyx / 1774xx .text i.cfcc: mov fpsr,r0 bic $!17,r0 mov r0,sps br ret i.setf: bic $m.ext,fpsr br ret i.setd: bis $m.ext,fpsr br ret i.seti: bic $m.lngi,fpsr br ret i.setl: bis $m.lngi,fpsr br ret badins: inc trapins br ret sret: mov $fpsr,r0 bic $17,(r0) tst (r5) bpl 1f bis $10,(r0) br ret 1: bne ret bis $4,(r0) ret: mov $sr1,r0 mov (r0)+,r1 mov (r0)+,r2 mov (r0)+,r3 mov (r0)+,r4 mov (r0)+,r5 mov (r0)+,sp mov sr0,r0 mov sps,-(sp) mov spc,-(sp) tst trapins bne 1f inc reenter rti 1: bpt freg: mov r5,r2 bic $!300,r2 asr r2 asr r2 asr r2 add $ac0,r2 rts pc fsrc: mov r5,r3 bic $!7,r3 / register asl r3 add $sr0,r3 mov r5,r0 bic $!70,r0 / mode asr r0 asr r0 jmp *1f(r0) .data 1: mod0 mod1 mod2 mod3 mod4 mod5 mod6 mod7 .text mod24f: mov $4,r0 bit $m.ext,fpsr beq 1f add $4,r0 1: rts pc mod24d: mov $8,r0 bit $m.ext,fpsr beq 1f sub $4,r0 1: rts pc mod242: mov $2,r0 rts pc mod24i: mov $2,r0 bit $m.lngi,fpsr beq 1f add $2,r0 1: rts pc mod0: jmp *(r1)+ mod0f: sub $sr0,r3 / get fp ac cmp r3,$6*2 bhis badi1 asl r3 asl r3 add $ac0,r3 tst (r1)+ rts r1 mod0ra: bit $m.lngi,fpsr bne badi1 mod0r: cmp r3,$ssp bhis badi1 mod0rx: tst (r1)+ rts r1 mod1: cmp r3,$spc beq badi1 mov (r3),r3 br check mod2: mov (r3),-(sp) jsr pc,*2(r1) cmp r3,$spc bne 1f mov $2,r0 mov *(r3),pctmp mov $pctmp,(sp) 1: add r0,(r3) mov (sp)+,r3 br check mod3: mov *(r3),-(sp) add $2,(r3) mov (sp)+,r3 br check mod4: cmp r3,$spc / test pc beq badi1 jsr pc,*2(r1) sub r0,(r3) mov (r3),r3 br check mod5: cmp r3,$spc beq badi1 sub $2,(r3) mov *(r3),r3 br check mod6: mov *spc,-(sp) add $2,spc add (r3),(sp)  mov (sp)+,r3 br check mod7: jsr r1,mod6; ..; .. mov (r3),r3 br check badi1: jmp badins check: bit $1,r3 bne badi1 cmp (r1)+,(r1)+ rts r1 setab: mov $asign,r0 jsr pc,seta mov r3,r2 mov $bsign,r0 seta: clr (r0) mov (r2)+,r1 mov r1,-(sp) beq 1f blt 2f inc (r0)+ br 3f 2: dec (r0)+ 3: bic $!177,r1 bis $200,r1 br 2f 1: clr (r0)+ 2: mov r1,(r0)+ mov (r2)+,(r0)+ bit $m.ext,fpsr beq 2f mov (r2)+,(r0)+ mov (r2)+,(r0)+ br 3f 2: clr (r0)+ clr (r0)+ 3: mov (sp)+,r1 asl r1 clrb r1 swab r1 sub $200,r1 mov r1,(r0)+ / exp rts pc norm: mov $areg,r0 mov (r0)+,r1 mov r1,-(sp) mov (r0)+,r2 bis r2,(sp) mov (r0)+,r3 bis r3,(sp) mov (r0)+,r4 bis r4,(sp)+ bne 1f clr asign rts pc 1: bit $!377,r1 beq 1f clc ror r1 ror r2 ror r3 ror r4 inc (r0) br 1b 1: bit $200,r1 bne 1f asl r4 rol r3 rol r2 rol r1 dec (r0) br 1b 1: mov r4,-(r0) mov r3,-(r0) mov r2,-(r0) mov r1,-(r0) rts pc mov (r2)+,(r0)+ br 3f 2: clr (r0)+ clr (r0)+ 3: mov (sp)+,r1 asl r1 clrb / fp2 -- floating point simulation i.ldx: mov (r3)+,(r2)+ mov (r3)+,(r2)+ bit $m.ext,fpsr beq 1f mov (r3)+,(r2)+ mov (r3)+,(r2)+ rts pc 1: clr (r2)+ clr (r2)+ rts pc i.stx: mov (r2)+,(r3)+ mov (r2)+,(r3)+ bit $m.ext,fpsr beq 1f mov (r2)+,(r3)+ mov (r2)+,(r3)+ 1: rts pc i.clrx: clr (r3)+ clr (r3)+ bit $m.ext,fpsr beq 1f clr (r3)+ clr (r3)+ 1: rts pc i.negx: tst (r3) beq 1f add $100000,(r3) 1: rts pc i.absx: bic $!77777,(r3) rts pc i.tstx: rts pc i.cmpx: mov $areg,r5 tst (r2) bge 1f tst (r3) bge 1f cmp (r2),(r3) bgt 4f blt 3f 1: cmp (r2)+,(r3)+ bgt 3f blt 4f cmp (r2)+,(r3)+ bne 1f bit $m.ext,fpsr beq 2f cmp (r2)+,(r3)+ bne 1f cmp (r2)+,(r3)+ beq 2f 1: bhi 3f 4: mov $1,(r5) rts pc 3: mov $-1,(r5) rts pc 2: clr (r5) rts pc i.ldcyx: mov (r3)+,(r2)+ mov (r3)+,(r2)+ bit $m.ext,fpsr bne 1f mov (r3)+,(r2)+ mov (r3)+,(r2)+ rts pc 1: clr (r2)+ clr (r2)+ rts pc i.stcxy: mov (r2)+,(r3)+ mov (r2)+,(r3)+ bit $m.ext,fpsr bne 1f clr (r3)+ clr (r3)+ 1: rts pc i.ldcjx: mov $asign,r0 mov $1,(r0)+ mov (r3)+,(r0)+ bit $m.lngi,fpsr beq 1f mov (r3)+,(r0)+ clr (r0)+ clr (r0)+ mov $32.-8,(r0)+ jmp saret 1: clr (r0)+ clr (r0)+ clr (r0)+ mov $16.-8,(r0) jmp saret i.stcxj: mov r3,r5 mov $asign,r0 jsr pc,seta mov $areg,r0 mov (r0)+,r1 mov (r0)+,r2 mov (r0)+,r3 mov aexp,r0 1: cmp r0,$48.-8 bge 1f clc ror r1 ror r2 ror r3 inc r0 br 1b 1: bgt xoflo tst r1 bne xoflo 1: bit $m.lngi,fpsr beq 1f tst asign bge 2f neg r3 adc r2 bcs 2f neg r2 2: mov r2,(r5) mov r3,2(r5) rts pc 1: tst r2 bne xoflo tst asign bge 2f neg r3 2: mov r3,(r5) rts pc xoflo: bis $1,fpsr / set fixed overflow (carry) jmp ret i.ldexp: mov $asign,r0 jsr pc,seta mov (r3),aexp jsr pc,reta jmp sret i.stexp: mov $asign,r0 jsr pc,seta mov aexp,(r3) mov r3,r5 jmp sret i.ldfps: mov (r3),fpsr jmp ret i.stfps: mov fpsr,(r3) jmp ret br 1b 1: bgt xoflo tst r1 bne xoflo 1: bit $m.lngi,fpsr beq 1f tst asign bge 2f neg r3 adc r/ fp3 -- floating simulation i.addx: jsr pc,setab br 1f i.subx: jsr pc,setab neg bsign 1: tst bsign beq reta tst asign beq retb mov areg+8,r1 sub breg+8,r1 blt 1f beq 2f cmp r1,$56. bge reta mov $breg,r0 br 4f 1: neg r1 cmp r1,$56. bge retb mov $areg,r0 4: mov r1,-(sp) mov (r0)+,r1 mov (r0)+,r2 mov (r0)+,r3 mov (r0)+,r4 add (sp),(r0) 1: clc ror r1 ror r2 ror r3 ror r4 dec (sp) bgt 1b mov r4,-(r0) mov r3,-(r0) mov r2,-(r0) mov r1,-(r0) tst (sp)+ 2: mov $areg+8,r1 mov $breg+8,r2 mov $4,r0 cmp asign,bsign bne 4f clc 1: adc -(r1) bcs 3f add -(r2),(r1) 2: dec r0 bne 1b br 5f 3: add -(r2),(r1) sec br 2b br 5f 4: clc 1: sbc -(r1) bcs 3f sub -(r2),(r1) 2: dec r0 bne 1b br 5f 3: sub -(r2),(r1) sec br 2b saret: mov $areg,r1 5: tst (r1) bge 3f mov $areg+8,r1 mov $4,r0 clc 1: adc -(r1) bcs 2f neg (r1) 2: dec r0 bne 1b neg -(r1) 3: jsr pc,norm br reta retb: mov $bsign,r1 mov $asign,r2 mov $6,r0 1: mov (r1)+,(r2)+ dec r0 bne 1b reta: mov r5,r2 mov $asign,r0 tst (r0) beq unflo mov aexp,r1 cmp r1,$177 bgt ovflo cmp r1,$-177 blt unflo add $200,r1 swab r1 clc ror r1 tst (r0)+ bge 1f bis $100000,r1 1: bic $!177,(r0) bis (r0)+,r1 mov r1,(r2)+ mov (r0)+,(r2)+ bit $m.ext,fpsr beq 1f mov (r0)+,(r2)+ mov (r0)+,(r2)+ 1: rts pc unflo: clr (r2)+ clr (r2)+ bit $m.ext,fpsr beq 1f clr (r2)+ clr (r2)+ 1: rts pc ovflo: bis $2,fpsr / set v-bit (overflow) jmp ret i.mulx: jsr pc,i.mul br saret i.modx: jsr pc,i.mul jsr pc,norm mov $asign,r0 mov $bsign,r1 mov $6,r2 1: mov (r0)+,(r1)+ dec r2 bne 1b clr r0 / count mov $200,r1 / bit clr r2 / reg offset 1: cmp r0,aexp bge 2f / in fraction bic r1,areg(r2) br 3f 2: bic r1,breg(r2) 3: inc r0 clc ror r1 bne 1b mov $100000,r1 add $2,r2 cmp r2,$8 blt 1b jsr pc,norm jsr pc,reta cmp r5,$ac1 beq 1f cmp r5,$ac3 beq 1f bit $200,breg bne 2f clr bsign 2: add $8,r5 jsr pc,retb sub $8,r5 1: rts pc i.divx: jsr pc,setab tst bsign beq ovflo sub bexp,aexp jsr pc,xorsign mov r5,-(sp) mov $areg,r0 mov (r0),r1 clr (r0)+ mov (r0),r2 clr (r0)+ mov (r0),r3 clr (r0)+ mov (r0),r4 clr (r0)+ mov $areg,r5 mov $400,-(sp) 1: mov $breg,r0 cmp (r0)+,r1 blt 2f bgt 3f cmp (r0)+,r2 blo 2f bhi 3f cmp (r0)+,r3 blo 2f bhi 3f cmp (r0)+,r4 bhi 3f 2: mov $breg,r0 sub (r0)+,r1 clr -(sp) sub (r0)+,r2 adc (sp) clr -(sp) sub (r0)+,r3 adc (sp) sub (r0)+,r4 sbc r3 adc (sp) sub (sp)+,r2 adc (sp) sub (sp)+,r1 bis (sp),(r5) 3: asl r4 rol r3  rol r2 rol r1 clc ror (sp) bne 1b mov $100000,(sp) add $2,r5 cmp r5,$areg+8 blo 1b tst (sp)+ mov (sp)+,r5 jmp saret i.mul: jsr pc,setab add bexp,aexp dec aexp jsr pc,xorsign mov r5,-(sp) mov $breg+4,r5 bit $m.ext,fpsr beq 1f add $4,r5 1: clr r0 clr r1 clr r2 clr r3 clr r4 1: asl r0 bne 2f inc r0 tst -(r5) 2: cmp r0,$400 bne 2f cmp r5,$breg bhi 2f mov $areg,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov (sp)+,r5 rts pc 2: clc ror r1 ror r2 ror r3 ror r4 bit r0,(r5) beq 1b mov r0,-(sp) mov $areg,r0 add (r0)+,r1 clr -(sp) add (r0)+,r2 adc (sp) clr -(sp) add (r0)+,r3 adc (sp) add (r0)+,r4 adc r3 adc (sp) add (sp)+,r2 adc (sp) add (sp)+,r1 mov (sp)+,r0 br 1b xorsign: cmp asign,bsign beq 1f mov $-1,asign rts pc 1: mov $1,asign rts pc bne 2f inc r0 tst -(r5) 2: cmp r0,$400 bne 2f cmp r5,$breg bhi 2f mov $areg,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov (sp)+,r5 rts pc 2: clc ror r1 ror r2 ror r3 ro/ fpx -- floating point simulation .data reenter: 1 .bss asign: .=.+2 areg: .=.+8 aexp: .=.+2 bsign: .=.+2 breg: .=.+8 bexp: .=.+2 fpsr: .=.+2 trapins: .=.+2 ac0: .=.+8. ac1: .=.+8. ac2: .=.+8. ac3: .=.+8. ac4: .=.+8. ac5: .=.+8. sr0: .=.+2 sr1: .=.+2 .=.+2 .=.+2 .=.+2 .=.+2 ssp: .=.+2 spc: .=.+2 sps: .=.+2 pctmp: .=.+8 -(r5) 2: cmp r0,$400 bne 2f cmp r5,$breg bhi 2f mov $areg,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov (sp)+,r5 rts pc 2: clc ror r1 ror r2 ror r3 ro! "W N F=    @ #D  D ҃TT ^ B ы e@W 0 ,"& 7    " 7 -  X e5PߋRTV`RߋR RT `Re `R7 t*p ȋ@E A Ze   ?    7? eEhead/buf.hL C E?head/bufx.hC FEhead/conf.h` $'F{head/file.hC HHhead/filex.hBC IIdRio2/rhf.cBC Dio2/rk.c Erio2/rp.cO Kio2/sys.cKC S}io2/tc.c" U"io2/tm.c ]io2/tty.c> :'ild/ld.c2DC sld/sysfix.c\ xlexcl/cformuC glexcl/input.c`C hlexcl/main.cC klexcl/output.cC llexcl/reject.cC m0&lexcl/unput.c]C nlexcl/yyless.c"C olexcl/yymore.c,C olexcl/yywrap.cC p lexgen1/a_tableC s(&lexgen1/access.cRC tlexgen1/anoth.c^C uhDlexgen1/auto.cX C wlexgen1/cform.c C x Glexgen1/chset.c]C yEUlexgen1/common.cC zKlexgen1/cpyact.c\C |~lexgen1/csubs.cC }Rlexgen1/ctrans.cC ~lexgen1/defrd.cC Llexgen1/defst.cC Olexgen1/errio.cC Llexgen1/extdef.cC ͱlexgen1/header.cC %lexgen1/lam.cP C lexgen1/ldefs.c'C V]lexgen1/lgen.cC lexgen2/move.cC lexgen2/nofree.cC +lexgen2/outstp.cC lexgen2/purge.c C [Klexgen2/range.cC ^lexgen2/rdcomm.cC lexgen2/rdrule.cC lexgen2/rprint.cAC Clexgen2/setflg.cC lexgen2/ssort.cC Blexgen2/start.cC @lexgen2/subset.c7C \lexgen2/tail.cC %lexgen2/usrtab.cPC .lil/com C аlil/common C Zlil/grammarC lil/lc.ciC 87lil/lex.cC -"ulil/lexl.l C 6lil/par.cC @=xlil/pass2c.cba II?lil/put.cQa RJ+lil/scrub5C asPlil/sem.cC bmlil/sim.cRC oHklil/str.cAC {F]lil/tab.cJC =lil/tabl.l C neqn/ne.g S ?lneqn/ne1.cS Pneqn/ne2.cS ;neqn/ne3.c S (neqn/ne4.c S Dneqn/ne5.cGS  neqn/ne6.cS  neqn/nelex.cS =neqn/e.gsS  ;neqn/e.hZS Eneqn/e0.cWS neqn/e1.cS ^Uneqn/e2.c]S Yneqn/e3.clS t`neqn/e4.cS tneqn/e5.cS ;neqn/e6.c6S }neqn/elex.c[S neqn/ne.hS uneqn/ne0.c#S nroff/suftab.s]portc1/cerror.cC  6portc1/cexit.cpC portc1/cflush.c:C 7portc1/cfree.cC J portc1/cgetc.cC portc1/ciodec.cvC PCportc1/clenf.cfC portc1/copen.cC ªportc1/cputc.c<C ê portc1/cwrd.cC ĪTportc1/exit.cC Ūportc1/ftoa.cC Ǫ portc2/maktab.cC Ϫ?portc2/portlb.cC Ъ}+portc2/printf.ci C Ҫ!!portc2/putch.c4C Ҫportc2/puts.cC ӪIportc2/relvec.cC Ԫl6portc2/rew.cC ժ [portc2/scan1.c C תC3portc2/scan2.cC ت6portc2/scan3.cCC ٪9portc2/system.cC ڪ-portc2/tmpnam.cbC ۪4portc2/unget.cC ݪportc2/wdleng.cC ު'rc/agen.rc prc/as.rc p)rc/aslib.rc pUsrc/bas.rc pMrc/cc.rc p6%rc/clib.rc! pyrc/cmd1.rcO pnrc/cmd2.rc prc/cmd3.rc prc/cmd4.rc prc/cmd5.rc prc/cmd6.rc pػrc/cref.rcT prc/nroff.rc q(crc/dc.rc; p%rc/fc.rct p_"rc/fc1.rc1 prc/fc2.rc prc/fc3.rc p rc/fc4.rcC pj rc/fciort.rc pDrc/fcld.rc pNrc/fclib.rc qgrc/fcsub.rc" q jrc/fed.rc q rc/form.rc q rc/io.rc qrc/ld.rc qrc/lex.rcb q1rc/lil.rc^ q,rc/neqn.rc q)rc/troff.rcP q^rc/opsys.rcy qNrc/portc.rc q[rc/sno.rc q$rc/system.rc q%;rc/tp.rc q'rc/unix.rc> q(ީrc/util.rc q*rc/yacc.rcO q0rc/adb.rc p2rc/term.rc q3Drc/font.rcy q5rc/eqn.rc p8xrc/tbl.rc q9rc/sccs.rc q:Rsno/sno.hRC @9sno/sno1.cC !Asno/sno2.c+C #Nsno/sno3.c<C %^e sno/sno4.cPC &fHtbl/tbl.cS o tbl/tbl0.cS Ãr9\tbl/tbl1.cQS ƃtZtbl/tbl2.cS Ƀv(\tbl/tbl3.cS ˃wWtbl/tbl4.c S ΃z&Mtbl/tbl5.c S уNtbl/tbl6.cS ԃ 7tbl/tbl7.c S փNtbl/tbl8.cS ك3tbl/tbl9.cS ܃Qtbl/tblb.cS ރ'tbl/tblc.cS ფu'tbl/tble.cS 䃧&tbl/tblf.cS 烩&tbl/tblg.cS ꃪ#tbl/tbli.cS 샬!tbl/tblm.cS ztbl/tbls.cS tbl/tblt.cS tbl/tblu.c S tbl/tblv.c S Fterm/code.300S yterm/300.cKS ySterm/300S.c^S yterm/300X.cKS yterm/300s.c^S yLJterm/37.cS y̖term/450-12.cqS yUterm/450.cYS yXRterm/450X.cZS zņterm/tn300.cuS zʾtp/tp1.s C _,tp/tp2.sC tp/tp3.sYC tp/tp4.smC a2util/copy.s C  util/dldr.sC util/dli.sC )util/dtf.sC butil/hpboot.s]C "futil/list.s C *tutil/loadC 1util/mkconf.c3 ['2util/mkconf.h' ]'L4util/mkdata.c- O util/mkconf.o? futil/mkdata.o8[ lutil/rkf.s*C *hutil/tboot.s C ,hutil/uboot.s C 0yacc/dextern2C 0'yacc/main.cpC yacc/opar.c C yacc/parser.c C uyacc/y0.cC tAyacc/y1.ca yacc/y2.c.C yacc/y3.c%a yacc/y4.c 'C yacc/y5.c=C -[Nyacc/yopti.c9C /yacc/zacc.c C Lyacc/zerr.cC Myacc/zinit.c C N7/* * Each buffer in the pool is usually doubly linked into 2 lists: * the device with which it is currently associated (always) * and also on a list of blocks available for allocation * for other use (usually). * The latter list is kept in last-used order, and the two * lists are doubly linked to make it easy to remove * a buffer from one list when it was found by * looking through the other. * A buffer is on the available list, and is liable * to be reassigned to another disk block, if and only * if it is not marked BUSY. When a buffer is busy, the * available-list pointers can be used for other purposes. * Most drivers use the forward ptr as a link in their I/O * active queue. * A buffer header contains all the information required * to perform I/O. * Most of the routines which manipulate these things * are in bio.c. */ struct buf { int b_flags; /* see defines below */ struct buf *b_forw; /* headed by devtab of b_dev */ struct buf *b_back; /* " */ struct buf *av_forw; /* position on free list, */ struct buf *av_back; /* if not BUSY*/ int b_dev; /* major+minor device name */ int b_wcount; /* transfer count (usu. words) */ char *b_addr; /* low order core address */ char *b_xmem; /* high order core address */ char *b_blkno; /* block # on device */ char b_error; /* returned after I/O */ char *b_resid; /* words not transferred after error */ }; /* * Each block device has a devtab, which contains private state stuff * and 2 list heads: the b_forw/b_back list, which is doubly linked * and has all the buffers currently associated with that major * device; and the d_actf/d_actl list, which is private to the * device but in fact is always used for the head and tail * of the I/O queue for the device. * Various routines in bio.c look at b_forw/b_back * (notice they are the same as in the buf structure) * but the rest is private to each device driver. */ struct devtab { char d_active; /* busy flag */ char d_errcnt; /* error count (for recovery) */ struct buf *b_forw; /* first buffer for this dev */ struct buf *b_back; /* last buffer for this dev */ struct buf *d_actf; /* head of I/O queue */ struct buf *d_actl; /* tail of I/O queue */ }; /* * These flags are kept in b_flags. */ #define B_WRITE 0 /* non-read pseudo-flag */ #define B_READ 01 /* read when I/O occurs */ #define B_DONE 02 /* transaction finished */ #define B_ERROR 04 /* transaction aborted */ #define B_BUSY 010 /* not on av_forw/back list */ #define B_PHYS 020 /* Physical IO potentially using UNIBUS map */ #define B_MAP 040 /* This block has the UNIBUS map allocated */ #define B_WANTED 0100 /* issue wakeup when BUSY goes off */ #define B_AGE 0200 /* delayed write for correct aging */ #define B_ASYNC 0400 /* don't wait for I/O completion */ #define B_DELWRI 01000 /* don't write till block leaves available list */ e B_DONE 02 /* transaction finished */ #define B_ERROR 04 /* transaction aborted */ #define B_BUSY 010 /* not on av_forw/back list */ #define B_PHYS 020 /* Physical IO potentially /* * Allocation of buffer headers */ struct buf buf[NBUF]; /* * Head of the available list for buffers */ struct buf bfreelist; es off */ #define B_AGE 0200 /* delayed write for correct aging */ #define B_ASYNC 0400 /* don't wait for I/O completion */ #define B_DELWRI 01000 /* don't write till block leaves available list */ e B_DONE 02 /* transaction finished */ #define B_ERROR 04 /* transaction aborted */ #define B_BUSY 010 /* not on av_forw/back list */ #define B_PHYS 020 /* Physical IO potentially /* * Used to dissect integer device code * into major (driver designation) and * minor (driver parameter) parts. */ struct { char d_minor; char d_major; }; /* * Declaration of block device * switch. Each entry (row) is * the only link between the * main unix code and the driver. * The initialization of the * device switches is in the * file conf.c. */ struct bdevsw { int (*d_open)(); int (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* * Character device switch. */ struct cdevsw { int (*d_open)(); int (*d_close)(); int (*d_read)(); int (*d_write)(); int (*d_sgtty)(); } cdevsw[]; struct ctlsw { int (*d_param)(); int (*d_mctl)(); } ctlsw[]; struct linesw { int (*l_open)(); int (*l_close)(); int (*l_read)(); int (*l_write)(); int (*l_rcvd)(); int (*l_xmtd)(); int (*l_mt)(); int (*l_sgtty)(); } linesw[]; file conf.c. */ struct bdevsw { int (*d_open)(); int (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* * Character device switch. */ struct /* * One file structure is allocated * for each open/creat/pipe call. * Main use is to hold the read/write * pointer associated with each open * file. */ struct file { char f_flag; char f_count; /* reference count */ struct inode *f_inode; /* pointer to inode structure */ char *f_offset[2]; /* read/write character pointer */ }; /* flags */ #define FREAD 01 #define FWRITE 02 #define FPIPE 04 nt (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* * Character device switch. */ struct /* * Allocation for the file table. */ struct file file[NFILE]; call. * Main use is to hold the read/write * pointer associated with each open * file. */ struct file { char f_flag; char f_count; /* reference count */ struct inode *f_inode; /* pointer to inode structure */ char *f_offset[2]; /* read/write character pointer */ }; /* flags */ #define FREAD 01 #define FWRITE 02 #define FPIPE 04 nt (*d_close)(); int (*d_strategy)(); int *d_tab; } bdevsw[]; /* * Character device switch. */ struct /* * Definition of the unix super block. * The root super block is allocated and * read in iinit/alloc.c. Subsequently * a super block is allocated and read * with each mount (smount/sys3.c) and * released with unmount (sumount/sys3.c). * A disk block is ripped off for storage. * See alloc.c for general alloc/free * routines for free list and I list. */ struct filsys { char *s_isize; /* size in blocks of I list */ char *s_fsize; /* size in blocks of entire volume */ int s_nfree; /* number of in core free blocks (0-100) */ int s_free[100]; /* in core free blocks */ int s_ninode; /* number of in core I nodes (0-100) */ int s_inode[100]; /* in core free I nodes */ char s_flock; /* lock during free list manipulation */ char s_ilock; /* lock during I list manipulation */ char s_fmod; /* super block modified flag */ char s_ronly; /* mounted read-only flag */ long s_time; /* current date of last update */ int pad[50]; }; ize; /* size in blocks of entire volume */ int s_nfree; /* number of in/* * Inode structure as it appears on * the disk. Not used by the system, * but by things like check, df, dump. */ struct inode { int i_mode; char i_nlink; char i_uid; char i_gid; char i_size0; char *i_size1; int i_addr[8]; int i_atime[2]; int i_mtime[2]; }; /* modes */ #define IALLOC 0100000 #define IFMT 060000 #define IFDIR 040000 #define IFCHR 020000 #define IFBLK 060000 #define ILARG 010000 #define ISUID 04000 #define ISGID 02000 #define ISVTX 01000 #define IREAD 0400 #define IWRITE 0200 #define IEXEC 0100 as it appears on * the disk. Not used by the system, * but by things like check, df, dump. */ struct inode { int i_mode; char i_nlink; char i_uid; char i_gid; char i_size0; char *i_size1; int i_addr[8]; int i_atime[2]; int i_mtime[2]; }; /* modes */ #define IALLOC 0100000 #define IFMT 060000 #define IFDIR 040000 #define IFCHR 020000 #define IFBLK 060000 #define ILARG 010000 #define ISUID 04000 #define ISGID 02000 #define ISVTX 01000 #define IREAD 0400 #define IWRITE 020/* * The I node is the focus of all * file activity in unix. There is a unique * inode allocated for each active file, * each current directory, each mounted-on * file, text file, and the root. An inode is 'named' * by its dev/inumber pair. (iget/iget.c) * Data, from mode on, is read in * from permanent inode on volume. */ struct inode { char i_flag; char i_count; /* reference count */ int i_dev; /* device where inode resides */ int i_number; /* i number, 1-to-1 with device address */ int i_mode; char i_nlink; /* directory entries */ char i_uid; /* owner */ char i_gid; /* group of owner */ char i_size0; /* most significant of size */ char *i_size1; /* least sig */ int i_addr[8]; /* device addresses constituting file */ int i_lastr; /* last logical block read (for read-ahead) */ }; /* flags */ #define ILOCK 01 /* inode is locked */ #define IUPD 02 /* inode has been modified */ #define IACC 04 /* inode access time to be updated */ #define IMOUNT 010 /* inode is mounted on */ #define IWANT 020 /* some process waiting on lock */ #define ITEXT 040 /* inode is pure text prototype */ /* modes */ #define IALLOC 0100000 /* file is used */ #define IFMT 060000 /* type of file */ #define IFDIR 040000 /* directory */ #define IFCHR 020000 /* character special */ #define IFBLK 060000 /* block special, 0 is regular */ #define ILARG 010000 /* large addressing algorithm */ #define ISUID 04000 /* set user id on execution */ #define ISGID 02000 /* set group id on execution */ #define ISVTX 01000 /* save swapped text even after use */ #define IREAD 0400 /* read, write, execute permissions */ #define IWRITE 0200 #define IEXEC 0100 le is used */ #define IFMT 060000 /* type of file */ #define IFDIR 040000 /* directory */ #define IFCHR 020000 /* character special */ #define IFBLK 060000 /* block special, 0 is regular */ #define ILARG 010000 /* large addressing algorithm */ #define ISUID 04000 /* set user id on execution */ #define ISGID 02000 /* set group id on execution */ #define ISVTX 0/* * Allocation of the inode table */ struct inode inode[NINODE]; read, write, execute permissions */ #define IWRITE 0200 #define IEXEC 0100 le is used */ #define IFMT 060000 /* type of file */ #define IFDIR 040000 /* directory */ #define IFCHR 020000 /* character special */ #define IFBLK 060000 /* block special, 0 is regular */ #define ILARG 010000 /* large addressing algorithm */ #define ISUID 04000 /* set user id on execution */ #define ISGID 02000 /* set group id on execution */ #define ISVTX 0/* * Interprocess Communication Control Structures */ /* * common flags */ #define IP_PERM 03 /* scope permission mask */ #define IP_ANY 0 /* system scope */ #define IP_UID 01 /* userid scope */ #define IP_GID 02 /* groupid scope */ #define IP_WANTED 0200 /* resource is desired */ struct ipaword { char ip_flag; char ip_id; }; /* * semaphore control */ #define PSEMI4 1 /* semi4 sleep priority */ #define S_TYPE 0100 /* semaphore type mask */ #define S_LU 0 /* lock-unlock type */ #define S_PV 0100 /* p-v type */ #define LOCK 0 #define UNLOCK 1 #define TLOCK 2 #define P 3 #define V 4 #define TEST 5 #define ASEMI 6 #define FSEMI 7 struct semi4s { int sem_lock; int sem_cnt; /*use count */ char sem_flag; char sem_id; /* id for determining scope */ }; /* * message control */ #define PMSG 5 /* message sleep priority */ #define MAXMLEN 212 /* max message length in bytes */ #define MAXMSG 5 /* max number unreceived msgs per process */ #define MSGIO 02 /* tell iomove() this is msg */ #define MSGIN 0 /* same as B_WRITE */ #define MSGOUT 01 /* same as B_READ */ #define MDISAB 0 #define MENAB 1 #define MSEND 2 #define MSENDW 3 #define MRECV 4 #define MRECVW 5 struct msghdr { struct msghdr *mq_forw; int mq_size; int mq_sender; int mq_type; }; struct msgqhdr { struct msghdr *mq_forw; /* note same position as in msghdr */ struct msghdr *mq_last; int *mq_procp; char mq_flag; char mq_cnt; }; x number unreceived msgs per process */ #define MSGIO 02 /* tell iomove() thstruct semi4s semi4s[NLOCK]; /* same as B_WRITE */ #define MSGOUT 01 /* same as B_READ */ #define MDISAB 0 #define MENAB 1 #define MSEND 2 #define MSENDW 3 #define MRECV 4 #define MRECVW 5 struct msghdr { struct msghdr *mq_forw; int mq_size; int mq_sender; int mq_type; }; struct msgqhdr { struct msghdr *mq_forw; /* note same position as in msghdr */ struct msghdr *mq_last; int *mq_procp; char mq_flag; char mq_cnt; }; x number unreceived msgs per process */ #define MSGIO 02 /* tell iomove() th/* * tunable variables */ #define NBUF 15 /* size of buffer cache */ #define NINODE 100*1 /* number of in core inodes */ #define NFILE 100*1 /* number of in core file structures */ #define NMOUNT 5 /* number of mountable file systems */ #define MAXMEM (64*32) /* max core per process - first # is Kw */ #define MAXUMEM (28672) /* maximum amt. of user memory in mem blocks */ #define SSIZE 20 /* initial stack size (*64 bytes) */ #define SINCR 20 /* increment of stack (*64 bytes) */ #define NOFILE 20  /* max open files per process */ #define FCLFILE 15 /* First file auto-closed on exec */ #define CANBSIZ 256 /* max size of typewriter line */ #define CMAPSIZ 50 /* size of core allocation area */ #define SMAPSIZ 50 /* size of swap allocation area */ #define NCALL 20 /* max simultaneous time callouts */ #define NPROC 50*1 /* max number of processes */ #define NTEXT 20 /* max number of pure texts */ #define NCLIST 100*1 /* max total clist size */ #define HZ 60 /* Ticks/second of the clock */ #define MSGBUFS 128 /* Characters saved from error messages */ #define NCARGS 5120 /* # characters in exec arglist */ #define NLOCK 10 /* max number semaphores */ #define NOLOCK 4 /* max semaphores per process */ #define NMQHDR 10 /* number message q headers */ #define MSGMEM 50 /* memory for messages (*32 bytes) */ #define MMAPSIZ 52 /* size of msg allocation area */ /* * priorities * probably should not be * altered too much */ #define PSWP -100 #define PINOD -90 #define PRIBIO -50 #define PPIPE 1 #define PWAIT 40 #define PSLEP 90 #define PUSER 100 /* * signals * dont change */ #define NSIG 20 /* * No more than 32 signals (1-33) because they are * stored in bits in a (long) word. */ #define SIGHUP 1 /* hangup */ #define SIGINT 2 /* interrupt (rubout) */ #define SIGQIT 3 /* quit (FS) */ #define SIGINS 4 /* illegal instruction */ #define SIGTRC 5 /* trace or breakpoint */ #define SIGIOT 6 /* iot */ #define SIGEMT 7 /* emt */ #define SIGFPT 8 /* floating exception */ #define SIGKIL 9 /* kill, uncatchable termination */ #define SIGBUS 10 /* bus error */ #define SIGSEG 11 /* segmentation violation */ #define SIGSYS 12 /* bad system call */ #define SIGPIPE 13 /* end of pipe */ #define SIGCLK 14 /* alarm clock */ #define SIGTRM 15 /* Catchable termination */ #define SIGCLD 18 /* Death of a child */ /* * fundamental constants * cannot be changed */ #define USIZE 16 /* size of user block (*64) */ #define NULL 0 #define NODEV (-1) #define ROOTINO 1 /* i number of all roots */ #define DIRSIZ 14 /* max characters per directory */ /* * structure to access an * integer in bytes */ struct { char lobyte; char hibyte; }; /* * structure to access an integer */ struct { int integ; }; /* * structure to access a long as integers */ struct { int hiword; int loword; }; /* * Certain processor registers */ #define PS 0177776 #define KL 0177560 #define SW 0177570 /* * Some macros for units conversion */ /* Core clicks (64 bytes) to segments */ #define ctos(x) ((x+127)>>7) /* Core clicks (64 bytes) to blocks */ #define ctob(x) ((x+7)>>3) ure to access an * integer in bytes */ struct { char lobyte; char hibyte; }; /* * structure to access an integer */ struct { int integ; }; /* * structure to access a long as integers */ struct { int hiword; int loword; }; /* * Certain processor registers */ #define PS 0177776 #define KL 0177560 #define SW 0177570 /* * Some macros for units conversion */ /* Core clicks (64 bytes) to segments */ #define ctos(x) ((x+127)>>7) /* Core clicks (64/* * One structure allocated per active * process. It contains all data needed * about the process while the * process may be swapped out. * Other per process data (user.h) * is swapped with the process. */ struct proc { char p_stat; char p_flag; char p_pri; /* priority, negative is high */ char p_time; /* resident time for scheduling */ char p_cpu; /* cpu usage for scheduling */ char p_nice; /* nice for cpu usage */ long p_sig; /* signals pending to this process */ int p_uid; /* user id, used to direct tty signals */ int p_pgrp; /* name of process group leader */ int p_pid; /* unique process id */ int p_ppid; /* process id of parent */ int p_addr; /* address of swappable image */ int p_size; /* size of swappable image (*64 bytes) */ int p_wchan; /* event process is awaiting */ int *p_textp; /* pointer to text structure */ int *p_link; /* linked list of running processes */ int p_clktim; /* time to alarm clock signal */ }; /* stat codes */ #define SSLEEP 1 /* awaiting an event */ #define SWAIT 2 /* (abandoned state) */ #define SRUN 3 /* running */ #define SIDL 4 /* intermediate state in process creation */ #define SZOMB 5 /* intermediate state in process termination */ #define SSTOP 6 /* process being traced */ /* flag codes */ #define SLOAD 01 /* in core */ #define SSYS 02 /* scheduling process */ #define SLOCK 04 /* process cannot be swapped */ #define SSWAP 010 /* process is being swapped out */ #define STRC 020 /* process is being traced */ #define SWTED 040 /* another tracing flag */ /* * Structure used to access saved times and status * of a dead processs, by the parent. * Overlays the proc structure. */ struct xproc { char p_stat; char p_flag; char p_pri; /* priority, negative is high */ char p_time; /* resident time for scheduling */ char p_cpu; /* cpu usage for scheduling */ char p_nice; /* nice for cpu usage */ long p_sig; /* signals pending to this process */ int p_uid; /* user id, used to direct tty signals */ int p_pgrp; /* name of process group leader */ int p_pid; /* unique process id */ int p_ppid; /* process id of parent */ int xp_xstat; /* Exit status for wait */ long xp_utime; /* user time, this proc */ long xp_stime; /* system time, this proc */ }; s high */ char p_time; /* resident time for scheduling */ char p_cpu; /* cpu usage for scheduling */ char p_nice; /* nice for cpu usage */ long p_sig; /* signals pending to this process */ int p_uid; /* user id, used to direct tty signals */ int p_pgrp; /* name of/* * Allocation of the proc table */ struct proc proc[NPROC]; struct proc *procend; /* highwater mark of proc table */ xit status for wait */ long xp_utime; /* user time, this proc */ long xp_stime; /* system time, this proc */ }; s high */ char p_time; /* resident time for scheduling */ char p_cpu; /* cpu usage for scheduling */ char p_nice; /* nice for cpu usage */ long p_sig; /* signals pending to this process */ int p_uid; /* user id, used to direct tty signals */ int p_pgrp; /* name of/* * Location of the users' stored * registers relative to R0. * Usage is u.u_ar0[XX]. */ #define R0 (0) #define R1 (-2) #define R2 (-9) #define R3 (-8) #define R4 (-7) #define R5 (-6) #define R6 (-3) #define R7 (1) #define RPS (2) #define TBIT 020 /* PS trace bit */ ime for scheduling */ char p_cpu; /* cpu usage for scheduling */ char p_nice; /* nice for cpu usage */ long p_sig; /* signals pending to this process */ int p_uid; /* user id, used to direct tty signals */ int p_pgrp; /* name of/* * KT-11 addresses and bits. */ #define UISD 0177600 /* first user I-space descriptor register */ #define UISA 0177640 /* first user I-space address register */ #define UDSA 0177660 /* first user D-space address register */ #define RO 02 /* access abilities */ #define RW 06 #define ED 010 /* extend direction */ #define TX 020 /* Software: text segment */ /* * structure used to address * a sequence of integers. */ struct { int r[]; }; int *ka6; /* 11/40 KISA6; 11/45 KDSA6 */ /* * address to access 11/70 UNIBUS map */ #define UBMAP 0170200 77600 /* first user I-space descriptor register */ #define UISA 0177640 /* first user I-space address register */ #define UDSA 0177660 /* first user D-space address register */ #define RO 02 /* access abilities */ #define RW 06 #define ED 010 /* extend direction */ #define TX 020 /* Software: text segment */ /* * structure used to address * a sequence of integers. */ struct { int r[]; }; int *ka6; /* 11/40 KISA6; 11/45 KDSA6 */ /* * address t/* * Random set of variables * used by more than one * routine. */ char canonb[CANBSIZ]; /* buffer for erase and kill (#@) */ struct map { int m_size; char *m_addr; }; struct map coremap[CMAPSIZ]; /* space for core allocation */ struct map swapmap[SMAPSIZ]; /* space for swap allocation */ struct map ubmap[13]; /* Unibus Map allocation map */ int *rootdir; /* pointer to inode of root directory */ int *runq; /* head of linked list of running processes */ int cputype; /* type of cpu =40, 45, or 70 */ int lbolt; /* time of day in 60th not in time */ long time; /* time in sec from 1970 */ long tout; /* time of day of next sleep */ int *acctp; /* inode of accounting file */ struct { char ac_comm[DIRSIZ]; /* Accounting command name */ char ac_flag; /* Accounting flag (unused) */ char ac_uid; /* Accounting user ID */ long ac_date; /* Accounting start time of command */ long ac_etime; /* Accounting elapsed time */ long ac_utime; /* Accounting user time */ long ac_stime; /* Accounting system time */ } acctbuf; /* * The callout structure is for * a routine arranging * to be called by the clock interrupt * (clock.c) with a specified argument, * in a specified amount of time. * Used, for example, to time tab * delays on typewriters. */ struct callo { int c_time; /* incremental time */ int c_arg; /* argument to routine */ int (*c_func)(); /* routine */ } callout[NCALL]; /* * Mount structure. * One allocated on every mount. * Used to find the super block. */ struct mount { int m_dev; /* device mounted */ int *m_bufp; /* pointer to superblock */ int *m_inodp; /* pointer to mounted on inode */ } mount[NMOUNT]; /* * Nblkdev is the number of entries * (rows) in the block switch. It is * set in binit/bio.c by making * a pass over the switch. * Used in bounds checking on major * device numbers. */ int nblkdev; /* * Number of character switch entries. * Set by cinit/tty.c */ int nchrdev; int mpid; /* generic for unique process id's */ char runin; /* scheduling flag */ char runout; /* scheduling flag */ char runrun; /* scheduling flag */ char curpri; /* more scheduling */ int maxmem; /* actual max memory per process */ int *lks; /* pointer to clock device */ int rootdev; /* dev of root see conf.c */ int swapdev; /* dev of swap see conf.c */ int swplo; /* block number of swap space */ int nswap; /* size of swap space */ int updlock; /* lock for sync */ int rablock; /* block to be read ahead */ char regloc[]; /* locs. of saved user registers (trap.c) */ char msgbuf[MSGBUFS]; /* saved "printf" characters */ int blkacty; /* active block devices for error log */ int chracty; /* active character devices */ /* * Instrumentation */ int dk_busy; long dk_time[32]; long dk_numb[3]; long dk_wds[3]; long tk_nin; long tk_nout; ap see conf.c */ int swplo; /* block number of swap space */ int nswap; /* size of swap space */ int updlock; /* lock for sync */ int rablock; /* block to be read ahead */ char regloc[]; /* locs. of saved user registers (trap.c)/* * Text structure. * One allocated per pure * procedure on swap device. * Manipulated by text.c */ struct text { int x_daddr; /* disk address of segment */ int x_caddr; /* core address, if loaded */ int x_size; /* size (*64) */ int *x_iptr; /* inode of prototype */ char x_count; /* reference count */ char x_ccount; /* number of loaded references */ char x_flag; /* traced, written flags */ }; #define XTRC 01 /* Text may be written, exclusive use */ #define XWRIT 02 /* Text written into, must swap out */ #define XLOAD 04 /* Currently being read from file */ #define XLOCK 010 /* Being swapped in or out */ #define XWANT 020 /* Wanted for swapping */ int x_caddr; /* core address, if loaded */ int x_size; /* size (*64) */ int *x_iptr; /* inode of prototype */ char x_count; /* reference count */ char x_ccount; /* number of loaded references */ char x_flag; /* traced, written flags */ }; #define XTRC 01 /* Text may be written, exclusive use */ #define XWRIT 02 /* Text written into, mu/* * Allocation of the text table */ struct text text[NTEXT]; e */ #define XLOCK 010 /* Being swapped in or out */ #define XWANT 020 /* Wanted for swapping */ int x_caddr; /* core address, if loaded */ int x_size; /* size (*64) */ int *x_iptr; /* inode of prototype */ char x_count; /* reference count */ char x_ccount; /* number of loaded references */ char x_flag; /* traced, written flags */ }; #define XTRC 01 /* Text may be written, exclusive use */ #define XWRIT 02 /* Text written into, mu/* * A clist structure is the head * of a linked list queue of characters. * The characters are stored in 4-word * blocks containing a link and 6 characters. * The routines getc and putc (m45.s or m40.s) * manipulate these structures. */ struct clist { int c_cc; /* character count */ int c_cf; /* pointer to first block */ int c_cl; /* pointer to last block */ }; /* * A tty structure is needed for * each UNIX character device that * is used for normal terminal IO. * The routines in tty.c handle the * common code associated with * these structures. * The definition and device dependent * code is in each driver. (kl.c dc.c dh.c) */ struct tty { int t_dev; /* device number */ char t_discp; /* line discipline */ char t_dtype; /* device type (kl dl dc dh) */ int t_pgrp; /* process group name */ int *t_addr; /* device address (register or startup fcn) */ int t_speeds; /* output+input line speed */ int t_flags; /* mode, settable by stty call */ int t_state; /* internal state, not visible externally */ char t_linest; /* line state */ char t_char; /* character temporary */ struct clist t_rawq; /* input chars right off device */ struct clist t_canq; /* input chars after erase and kill */ struct clist t_outq; /* output list to device */ char t_delct; /* number of delimiters in raw q */ char t_col; /* printing column of device */ char t_erase; /* erase character */ char t_kill; /* kill character */ int t_lword; /* extra word reserved for new disciplines */ }; char partab[];  /* ASCII table: parity, character class */ #define TTIPRI 10 #define TTOPRI 20 #define CERASE '#' /* default special characters */ #define CEOT 004 #define CKILL '@' #define CQUIT 034 /* FS, cntl shift L */ #define CINTR 0177 /* DEL */ #define CXSTOP 01 /* SOH, cntl a */ #define CTOUT 040000 /* timeout character */ #define CPRES 0100000 /* character present (in low order byte) */ /* Character read errors */ #define PERROR 010000 /* parity error */ #define FRERROR 020000 /* framing error */ #define OVERRUN 040000 /* data overrun */ /* limits */ #define TTHIWAT 100 #define TTLOWAT 50 #define TTYHOG 256 /* modes */ #define HUPCL 01 #define XTABS 02 #define LCASE 04 #define ECHO 010 #define CRMOD 020 #define RAW 040 #define ODDP 0100 #define EVENP 0200 #define NLDELAY 001400 #define TBDELAY 006000 #define CRDELAY 030000 #define VTDELAY 040000 #define HDUP 0100000 /* Internal state bits */ #define TIMEOUT 01 /* Delay timeout in progress */ #define WOPEN 02 /* Waiting for open to complete */ #define ISOPEN 04 /* Device is open */ #define SSTART 010 /* Has special start routine at addr */ #define CARR_ON 020 /* Software copy of carrier-present */ #define BUSY 040 /* Output in progress */ #define ASLEEP 0100 /* Wakeup when output done */ #define XCLUDE 0200 /* Exclusive use flag against open */ #define XMTSTOP 0400 /* Output temporarily interrupted */ /* Hardware bits */ #define DONE 0200 /* Modem status bits */ #define SR 01 /* secondary receive */ #define CTS 02 /* clear to send */ #define CARRIER 04 /* main carrier receive */ /* Modem control operations */ #define FSTATUS 0 /* fetch modem status */ #define HUP 01 /* Hangup (turn off data terminal ready) */ #define DISABLE 02 /* hangup and disable modem interrupts */ #define TURNON 03 /* enable + data terminal ready */ /* TURNON operation permits independent setting of RQS and ST as follows */ #define RQS 04 /* request to send ('or' with TURNON) */ #define ST 010 /* secondary transmit ('or' with TURNON) */ /* ioctl commands */ #define GETD 0000 /* get line discipline */ #define CHNGD 0001 /* change line discp. and exec. subcmd */ #define GTTY 0010 /* gtty command */ #define STTY 0011 /* stty command */ #define STTYNF 0012 /* stty without flush */ #define FEK 0013 /* fetch erase and kill characters */ #define SEK 0014 /* set erase and kill characters */ #define XCLD 0015 /* prevent opens on channel */ #define UNSET 0200 /* unset line discipline */ #define SET 0201 /* set line discipline */ NON) */ /* ioctl commands */ #d/* * The user structure. * One allocated per process. * Contains all per process data * that doesn't need to be referenced * while the process is swapped. * The user block is USIZE*64 bytes * long; resides at virtual kernel * loc 140000; contains the system * stack per user; is cross referenced * with the proc structure for the * same process. */ struct user { int u_rsav[2]; /* save r5,r6 when exchanging stacks */ int u_fsav[25]; /* save fp registers */ /* rsav and fsav must be first in structure */ char u_segflg; /* IO flag: 0:user D; 1:system; 2:user I */ char u_error; /* return error code */ char u_uid; /* effective user id */ char u_gid; /* effective group id */ char u_ruid; /* real user id */ char u_rgid; /* real group id */ int u_procp; /* pointer to proc structure */ char *u_base; /* base address for IO */ char *u_count; /* bytes remaining for IO */ char *u_offset[2]; /* offset in file for IO */ int *u_cdir; /* pointer to inode of current directory */ char u_dbuf[DIRSIZ]; /* current pathname component */ char *u_dirp; /* current pointer to inode */ struct { /* current directory entry */ int u_ino; char u_name[DIRSIZ]; } u_dent; int *u_pdir; /* inode of parent directory of dirp */ int u_uisa[16]; /* prototype of segmentation addresses */ int u_uisd[16]; /* prototype of segmentation descriptors */ int u_ofile[NOFILE]; /* pointers to file structures of open files */ int u_arg[5]; /* arguments to current system call */ int u_tsize; /* text size (*64) */ int u_dsize; /* data size (*64) */ int u_ssize; /* stack size (*64) */ int u_sep; /* flag for I and D separation */ int u_qsav[2]; /* label variable for quits and interrupts */ int u_ssav[2]; /* label variable for swapping */ int u_signal[NSIG]; /* disposition of signals */ long u_utime; /* this process user time */ long u_stime; /* this process system time */ long u_cutime; /* sum of childs' utimes */ long u_cstime; /* sum of childs' stimes */ int *u_ar0; /* address of users saved R0 */ int u_prof[4]; /* profile arguments */ char u_intflg; /* catch intr from sys */ int u_ttyp; /* controlling tty pointer */ int u_ttyd; /* controlling tty dev */ struct { /* header of executable file */ int ux_mag; /* magic number */ int ux_tsize; /* text size */ int ux_dsize; /* data size */ int ux_bsize; /* bss size */ int ux_ssize; /* symbol table size */ int ux_entloc; /* entry location */ } u_exdata; int *u_semi4[NOLOCK]; /* semaphore control ptrs */ int *u_msgqhdr; /* ptr to message q header */ char u_comm[DIRSIZ]; long u_start; char u_acflag; int u_call; int u_narg; int u_nargc; int u_loc; int u_dev; int u_inode; int *u_rdir; /* root for this process */ /* kernel stack per user * extends from u + USIZE*64 * backward not to reach here */ }; /* u_error codes */ #define EPERM 1 #define ENOENT 2 #define ESRCH 3 #define EINTR 4 #define EIO 5 #define ENXIO 6 #define E2BIG 7 #define ENOEXEC 8 #define EBADF 9 #define ECHILD 10 #define EAGAIN 11 #define ENOMEM 12 #define EACCES 13 #define EFAULT 14 #define ENOTBLK 15 #define EBUSY 16 #define EEXIST 17 #define EXDEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 #define ETABLE 33 /*no table entries left*/ #define EFUNC 34 /*invalid operation requested*/ #define ENOMSG 35 /* no message on queue */ #define ENOALOC 36 /*resource not allocated or for proper purpose*/ #define EBIOCTL 37 /* invalid ioctl operation */ DEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 #define ETABLE 33 /*no table entries left*/ #define EFUNC 34 /*invalid operation requested*/ #define ENOMSG 35 /* no me/* * Allocation of the user structure. */ struct user u; d or for proper purpose*/ #define EBIOCTL 37 /* invalid ioctl operation */ DEV 18 #define ENODEV 19 #define ENOTDIR 20 #define EISDIR 21 #define EINVAL 22 #define ENFILE 23 #define EMFILE 24 #define ENOTTY 25 #define ETXTBSY 26 #define EFBIG 27 #define ENOSPC 28 #define ESPIPE 29 #define EROFS 30 #define EMLINK 31 #define EPIPE 32 #define ETABLE 33 /*no table entries left*/ #define EFUNC 34 /*invalid operation requested*/ #define ENOMSG 35 /* no me/* * "True" major device numbers for block devices. * Used for error logging purposes only. */ #define RK 0 #define RP 1 #define RF 2 #define TM 3 #define TC 4 #define HP 5 #define HT 6 #define HS 7 /* * IO statistics are kept for each physical unit of each block * device. Primary purpose is to establish a guesstimate * of error rates during error logging. */ struct iostat { long io_ops; /* number of read/writes */ long io_misc; /* number of "other" operations */ int io_unlog; /* number of unlogged errors */ }; /* * Template for the system configuration information * that is placed in the error log startup record. */ struct econfig { int e_bconf; /* block device configuration */ int e_cconf; /* character device configuration */ }; /* * Error log startup record template. */ struct estart { int e_type; /* error log record type */ long e_ctime; /* current time */ int es_cpu; /* type of cpu */ int es_mmr3; /* contents of Mem Mgmt Reg 3 */ char es_nbdev; /* number of block devices */ char es_ncdev; /* number of character devices */ struct econfig es_conf; /* device configuration for system */ }; /* * Error log termination record template. */ struct eend { int e_type; /* error log record type */ long e_ctime; /* current time */ }; /* * Error log time change record template. */ struct etchg { int e_type; /* error log record type */ long e_ctime; /* current time */ long e_ntime; /* "new" time */ }; /* * Error log block device record template. */ struct eblock { int e_type; /* error log record type */ long e_ctime; /* current time */ int e_dev; /* "true" major + minor device numbers */ struct iostat e_stat; /* IO statistics to date for this unit */ int e_bacty; /* other active block devices */ int e_cacty; /* other active character devices */ char e_rtry; /* number of retries */ char e_nreg; /* number of device registers logged */ int e_rloc; /* starting address of device registers */ int eb_bflg; /* buffer header flags */ int eb_wcnt; /* buffer header word count */ long eb_maddr; /* buffer memory address */ int eb_bno; /* block number on logical device */ }; /* * Error log message types */ #define E_NOACK 64 #define E_GO 010 /* startup record number */ #define E_STOP 011 /* stop record number */ #define E_TCHG 012 /* time change record number */ #define E_TYPE 060 /* device type mask */ #define E_BLK 020 /* block device error record number */ #define E_CHR 040 /* character device error record number */ #define E_CPU 060 /* cpu error record number */ #define E_RH70 0100 /* device uses RH controller */ #define E_FIRST 0 #define E_RETRY 1 #define E_EARLY 2 /* * Device error table. * Keeps information precious to the error logging routines. */ struct errtab { char e_devtyp; /* type of device*/ char e_nunit; /* number of physical units */ int e_devnum; /* "true" major + minor device number */ struct iostat *e_iostat; /* IO statistics array for this device */ struct iostat *e_aunit; /* IO statistics for currently active unit */ int *e_emsg; /* pointer to error record message */ }; /* * Macro for initializing the errtab */ #define etabinit(typ,nu,dn,is) typ,nu,(dn<<8),is,0,0 eps information precious to the error logging routines. */ struct errtab { char e_devtyp; /* type of device*/ char e_nunit; /* number of physical units */ int e_devnum; /* "true" major + minor device number */ struct iostat *e_iostat; /* IO statistics array for this device */ struct iostat *e_aunit; /* IO statist# /* */ #include "../head/param.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/systm.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/seg.h" /* * This is the set of buffers proper, whose heads * were declared in buf.h. There can exist buffer * headers not pointing here that are used purely * as arguments to the I/O routines to describe * I/O to be done-- e.g. swbuf, just below, for * swapping. */ char buffers[NBUF][514]; struct buf swbuf1; struct buf swbuf2; /* * Declarations of the tables for the magtape devices; * see bdwrite. */ int tmtab; int httab; /* * The following several routines allocate and free * buffers with various side effects. In general the * arguments to an allocate routine are a device and * a block number, and the value is a pointer to * to the buffer header; the buffer is marked "busy" * so that no on else can touch it. If the block was * already in core, no I/O need be done; if it is * already busy, the process waits until it becomes free. * The following routines allocate a buffer: * getblk * bread * breada * Eventually the buffer must be released, possibly with the * side effect of writing it out, by using one of * bwrite * bdwrite * bawrite * brelse */ /* * Read in (if necessary) the block and return a buffer pointer. */ bread(dev, blkno) { register struct buf *rbp; rbp = getblk(dev, blkno); if (rbp->b_flags&B_DONE)  return(rbp); rbp->b_flags =| B_READ; rbp->b_wcount = -256; (*bdevsw[dev.d_major].d_strategy)(rbp); iowait(rbp); return(rbp); } /* * Read in the block, like bread, but also start I/O on the * read-ahead block (which is not allocated to the caller) */ breada(adev, blkno, rablkno) { register struct buf *rbp, *rabp; register int dev; dev = adev; rbp = 0; if (!incore(dev, blkno)) { rbp = getblk(dev, blkno); if ((rbp->b_flags&B_DONE) == 0) { rbp->b_flags =| B_READ; rbp->b_wcount = -256; (*bdevsw[adev.d_major].d_strategy)(rbp); } } if (rablkno && !incore(dev, rablkno)) { rabp = getblk(dev, rablkno); if (rabp->b_flags & B_DONE) brelse(rabp); else { rabp->b_flags =| B_READ|B_ASYNC; rabp->b_wcount = -256; (*bdevsw[adev.d_major].d_strategy)(rabp); } } if (rbp==0) return(bread(dev, blkno)); iowait(rbp); return(rbp); } /* * Write the buffer, waiting for completion. * Then release the buffer. */ bwrite(bp) struct buf *bp; { register struct buf *rbp; register flag; rbp = bp; flag = rbp->b_flags; rbp->b_flags =& ~(B_READ | B_DONE | B_ERROR | B_DELWRI | B_AGE); rbp->b_wcount = -256; (*bdevsw[rbp->b_dev.d_major].d_strategy)(rbp); if ((flag&B_ASYNC) == 0) { iowait(rbp); brelse(rbp); } else if (flag&B_DELWRI) rbp->b_flags =| B_AGE; else geterror(rbp); } /* * Release the buffer, marking it so that if it is grabbed * for another purpose it will be written out before being * given up (e.g. when writing a partial block where it is * assumed that another write for the same block will soon follow). * This can't be done for magtape, since writes must be done * in the same order as requested. */ bdwrite(bp) struct buf *bp; { register struct buf *rbp; register struct devtab *dp; rbp = bp; dp = bdevsw[rbp->b_dev.d_major].d_tab; if (dp == &tmtab || dp == &httab) bawrite(rbp); else { rbp->b_flags =| B_DELWRI | B_DONE; brelse(rbp); } } /* * Release the buffer, start I/O on it, but don't wait for completion. */ bawrite(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; rbp->b_flags =| B_ASYNC; bwrite(rbp); } /* * release the buffer, with no I/O implied. */ brelse(bp) struct buf *bp; { register struct buf *rbp, **backp; register int sps; rbp = bp; if (rbp->b_flags&B_WANTED) wakeup(rbp); if (bfreelist.b_flags&B_WANTED) { bfreelist.b_flags =& ~B_WANTED; wakeup(&bfreelist); } if (rbp->b_flags&B_ERROR) rbp->b_dev.d_minor = -1; /* no assoc. on error */ sps = PS->integ; spl6(); if(rbp->b_flags & B_AGE) { backp = &bfreelist.av_forw; (*backp)->av_back = rbp; rbp->av_forw = *backp; *backp = rbp; rbp->av_back = &bfreelist; } else { backp = &bfreelist.av_back; (*backp)->av_forw = rbp; rbp->av_back = *backp; *backp = rbp; rbp->av_forw = &bfreelist; } rbp->b_flags =& ~(B_WANTED|B_BUSY|B_ASYNC|B_AGE); PS->integ = sps; } /* * See if the block is associated with some buffer * (mainly to avoid getting hung up on a wait in breada) */ incore(adev, blkno) { register int dev; register struct buf *bp; register struct devtab *dp; dev = adev; dp = bdevsw[adev.d_major].d_tab; for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) if (bp->b_blkno==blkno && bp->b_dev==dev) return(bp); return(0); } /* * Assign a buffer for the given block. If the appropriate * block is already associated, return it; otherwise search * for the oldest non-busy buffer and reassign it. * When a 512-byte area is wanted for some random reason * getblk can be called * with device NODEV to avoid unwanted associativity.  */ getblk(dev, blkno) { register struct buf *bp; register struct devtab *dp; extern lbolt; if(dev.d_major >= nblkdev) panic("blkdev"); loop: if (dev < 0) dp = &bfreelist; else { dp = bdevsw[dev.d_major].d_tab; if(dp == NULL) panic("devtab"); for (bp=dp->b_forw; bp != dp; bp = bp->b_forw) { if (bp->b_blkno!=blkno || bp->b_dev!=dev) continue; spl6(); if (bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED; sleep(bp, PRIBIO+1); spl0(); goto loop; } spl0(); notavail(bp); return(bp); } } spl6(); if (bfreelist.av_forw == &bfreelist) { bfreelist.b_flags =| B_WANTED; sleep(&bfreelist, PRIBIO+1); spl0(); goto loop; } spl0(); notavail(bp = bfreelist.av_forw); if (bp->b_flags & B_DELWRI) { bp->b_flags =| B_ASYNC; bwrite(bp); goto loop; } bp->b_flags = B_BUSY; bp->b_back->b_forw = bp->b_forw; bp->b_forw->b_back = bp->b_back; bp->b_forw = dp->b_forw; bp->b_back = dp; dp->b_forw->b_back = bp; dp->b_forw = bp; bp->b_dev = dev; bp->b_blkno = blkno; return(bp); } /* * Wait for I/O completion on the buffer; return errors * to the user. */ iowait(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; spl6(); while ((rbp->b_flags&B_DONE)==0) sleep(rbp, PRIBIO); spl0(); geterror(rbp); } /* * Unlink a buffer from the available list and mark it busy. * (internal interface) */ notavail(bp) struct buf *bp; { register struct buf *rbp; register int sps; rbp = bp; sps = PS->integ; spl6(); rbp->av_back->av_forw = rbp->av_forw; rbp->av_forw->av_back = rbp->av_back; rbp->b_flags =| B_BUSY; PS->integ = sps; } /* * Mark I/O complete on a buffer, release it if I/O is asynchronous, * and wake up anyone waiting for it. */ iodone(bp) struct buf *bp; { register struct buf *rbp; rbp = bp; if(rbp->b_flags&B_MAP) mapfree(rbp); rbp->b_flags =| B_DONE; if (rbp->b_flags&B_ASYNC) brelse(rbp); else { rbp->b_flags =& ~B_WANTED; wakeup(rbp); } } /* * Zero the core associated with a buffer. */ clrbuf(bp) int *bp; {  register *p; register c; p = bp->b_addr; c = 256; do *p++ = 0; while (--c); } /* * Initialize the buffer I/O system by freeing * all buffers and setting all device buffer lists to empty. */ binit() { register struct buf *bp; register struct devtab *dp; register int i; struct bdevsw *bdp; bfreelist.b_forw = bfreelist.b_back = bfreelist.av_forw = bfreelist.av_back = &bfreelist; for (i=0; ib_dev = -1; bp->b_wcount = -256; bp->b_addr = buffers[i]; bp->b_back = &bfreelist; bp->b_forw = bfreelist.b_forw; bfreelist.b_forw->b_back = bp; bfreelist.b_forw = bp; bp->b_flags = B_BUSY; brelse(bp); } i = 0; for (bdp = bdevsw; bdp->d_open; bdp++) { dp = bdp->d_tab; if(dp) { dp->b_forw = dp; dp->b_back = dp; } i++; } nblkdev = i; } /* * Device start routine for disks * and other devices that have the register * layout of the older DEC controllers (RF, RK, RP, TM) */ #define IENABLE 0100 #define WCOM 02 #define RCOM 04 #define GO 01 devstart(bp, devloc, devblk, hbcom) struct buf *bp; int *devloc; { register int *dp; register struct buf *rbp; register int com; dp = devloc; rbp = bp; *dp = devblk; /* block address */ *--dp = rbp->b_addr; /* buffer address */ *--dp = rbp->b_wcount; /* word count */ com = (hbcom<<8) | IENABLE | GO | ((rbp->b_xmem & 03) << 4); if (rbp->b_flags&B_READ) /* command + x-mem */ com =| RCOM; else com =| WCOM; *--dp = com; } /* * swap I/O */ /* * NOTE: THE SWAP DEVICE MAY NOT BE ON AN INVERTED DISK AREA */ swap(blkno, coreaddr, count, rdflg) { register struct buf *bp; bp = &swbuf1; if(bp->b_flags & B_BUSY) if((swbuf2.b_flags&B_WANTED) == 0) bp = &swbuf2; spl6(); while (bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED; sleep(bp, PSWP+1); } bp->b_flags = B_BUSY | B_PHYS | rdflg; bp->b_dev = swapdev; bp->b_wcount = - (count<<5); /* 32 w/block */ bp->b_blkno = blkno; bp->b_addr = coreaddr<<6; /* 64 b/block */ bp->b_xmem = (coreaddr>>10) & 077; (*bdevsw[swapdev>>8].d_strategy)(bp); spl6(); while((bp->b_flags&B_DONE)==0) sleep(bp, PSWP); if (bp->b_flags&B_WANTED) wakeup(bp); spl0(); bp->b_flags =& ~(B_BUSY|B_WANTED); if (bp->b_flags & B_ERROR) panic("IO err in swap"); } /* * make sure all write-behind blocks * on dev (or NODEV for all) * are flushed out. * (from umount and update) */ bflush(dev) { register struct buf *bp; loop: spl6(); for (bp = bfreelist.av_forw; bp != &bfreelist; bp = bp->av_forw) { if (bp->b_flags&B_DELWRI && (dev == NODEV||dev==bp->b_dev)) { bp->b_flags =| B_ASYNC; notavail(bp); bwrite(bp); goto loop; } } spl0(); } /* * Raw I/O. The arguments are * The strategy routine for the device * A buffer, which will always be a special buffer * header owned exclusively by the device for this purpose * The device number * Read/write flag * Essentially all the work is computing physical addresses and * validating them. */ physio(strat, abp, dev, rw, nblocks) struct buf *abp; int (*strat)(); char *nblocks; { register struct buf *bp; register char *base; register int nb; int ts; char *off; /* * Check to see if a partial read should be made for end of a * logical device; */ off = lshift(u.u_offset, -9); if(nblocks) { if(off >= nblocks) return; base = ldiv(u.u_count+511,512); /* amt to read/write */ nblocks =- off; /* blks left this filesys */ if(base > nblocks) { if(rw == B_WRITE) { u.u_error = ENXIO; return; } base = (base-nblocks)*512; u.u_count =- base; u.u_arg[1] =- base; } } bp = abp; base = u.u_base; /* * Check odd base, odd count, and address wraparound */ if (base&01 || u.u_count&01 || base>=base+u.u_count) goto bad; ts = (u.u_tsize+127) & ~0177; if (u.u_sep) ts = 0; nb = (base>>6) & 01777; /* * Check overlap with text. (ts and nb now * in 64-byte clicks) */ if (nb < ts) goto bad; /* * Check that transfer is either entirely in the * data or in the stack: that is, either * the end is in the data or the start is in the stack * (remember wraparound was already checked). */ if ((((base+u.u_count)>>6)&01777) >= ts+u.u_dsize && nb < 1024-u.u_ssize) goto bad; spl6(); while (bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED; sleep(bp, PRIBIO+1); } bp->b_flags = B_BUSY | B_PHYS | rw; bp->b_dev = dev; /* * Compute physical address by simulating * the segmentation hardware. */ bp->b_addr = base&077; base = (u.u_sep? UDSA: UISA)->r[nb>>7] + (nb&0177); bp->b_addr =+ base<<6; bp->b_xmem = (base>>10) & 077; bp->b_blkno = off; bp->b_wcount = -((u.u_count>>1) & 077777); bp->b_error = 0; u.u_procp->p_flag =| SLOCK; (*strat)(bp); spl6(); while ((bp->b_flags&B_DONE) == 0) sleep(bp, PRIBIO); u.u_procp->p_flag =& ~SLOCK; if (bp->b_flags&B_WANTED) wakeup(bp); if(runin) { runin = 0; wakeup(&runin); } spl0(); bp->b_flags =& ~(B_BUSY|B_WANTED); u.u_count = (-bp->b_resid)<<1; geterror(bp); return; bad: u.u_error = EFAULT; } /* * Pick up the device's error number and pass it to the user; * if there is an error but the number is 0 set a generalized * code. Actually the latter is always true because devices * don't yet return specific errors. */ geterror(abp) struct buf *abp; { register struct buf *bp; bp = abp; if (bp->b_flags&B_ERROR) if ((u.u_error = bp->b_error)==0) u.u_error = EIO; } ); bp->b_flags =& ~(B_BUSY|B_WANTED); u.u_count = (-bp->b_resid)<<1; geterror(bp); return; bad: u.u_error = EFAULT; } /* * Pick up the device's error number and pass it to the user; * if th# /* */ /* * DC-11 driver */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" /* * Base address of DC-11's. Minor device i is at * DCADDR + 10*i. */ #define DCADDR 0174000 /* Std is 174000 */ #define DCTYPE 02 /* * Number of DC's for which table space is allocated. */ #define NDC11 1 /* * Control bits in device registers */ #define IENABLE 0100 /* interrupt enable */ #define DTR 01 /* data terminal ready */ #define DCRQS 01 /* request to send */ #define DCST 0400 /* secondary transmit */ #define PARITY 040 #define DCOVRN 010000 /* data overrun */ #define MTRANS 040000 /* modem transition */ int ndc11 NDC11; struct tty dc11[NDC11]; struct dcregs { int dcrcsr; int dcrbuf; int dctcsr; int dctbuf; }; /* * Input-side speed and control bit table. * Each DC11 has 4 speeds which correspond to the 4 non-zero entries. * The table index is the same as the speed-selector * number for the DH11. * Attempts to set the speed to a zero entry are ignored. */ int dcrstab[] { 0, /* 0 baud */ 0, /* 50 baud */ 0, /* 75 baud */ 0, /* 110 baud */ 01101, /* 134.5 baud: 7b/ch, speed 0 */ 0111, /* 150 baud: 8b/ch, speed 1 */ 0, /* 200 baud */ 0121, /* 300 baud: 8b/ch, speed 2 */ 0, /* 600 baud */ 0131, /* 1200 baud */ 0, /* 1800 baud */ 0, /* 2400 baud */ 0, /* 4800 baud */ 0, /* 9600 baud */ 0, /* X0 */ 0, /* X1 */ }; /* * Transmitter speed table */ int dctstab[] { 0, /* 0 baud */ 0, /* 50 baud */ 0, /* 75 baud */ 0, /* 110 baud */ 0501, /* 134.5 baud: stop 1 */ 0511, /* 150 baud */ 0, /* 200 baud */ 0521, /* 300 baud */ 0, /* 600 baud */ 0531, /* 1200 baud */ 0, /* 1800 baud */ 0, /* 2400 baud */ 0, /* 4800 baud */ 0, /* 9600 baud */ 0, /* X0 */ 0, /* X1 */ }; /* * Open a DC11. */ dcopen(dev, flag) { register struct tty *tp; register *addr; if (dev.d_minor >= NDC11) { u.u_error = ENXIO; return; } tp = &dc11[dev.d_minor]; tp->t_addr = addr = DCADDR + dev.d_minor*8; tp->t_dev = dev; tp->t_dtype = DCTYPE; if (flag) { addr->dcrcsr =| IENABLE; (*linesw[tp->t_discp].l_open)(dev, tp); } } /* * Close a dc11 */ dcclose(dev, flag) { register struct tty *tp; tp = &dc11[dev.d_minor]; (*linesw[tp->t_discp].l_close)(dev, tp); } dcparam(dev, atp) struct tty *atp; { register struct tty *tp; register r; tp = atp; if (r = dcrstab[tp->t_speeds.lobyte&017]) tp->t_addr->dcrcsr = r; if (r = dctstab[tp->t_speeds.hibyte&017]) tp->t_addr->dctcsr = r; } /* * Modem control for DC 11. */ dcmctl(dev, action) { register struct tty *tp; register int sps, *addr; int tcsr, status; tp = &dc11[dev.d_minor]; addr = tp->t_addr; status = 0; sps = PS->integ; spl5(); switch(action&03) { case FSTATUS: tcsr = addr->dctcsr; status = (addr->dcrcsr&CARRIER)|(tcsr&CTS)|((tcsr>>15)&SR); break; case DISABLE: case HUP: addr->dcrcsr =& ~DTR; break; case TURNON: /* * Set data terminal ready. Also set primary and secondary * carrier status according to bits 2 and 3 of "action" */ addr->dcrcsr =| DTR; if(action&ST) addr->dcrcsr =| DCST; else addr->dcrcsr =& ~DCST; if(action&RQS) addr->dctcsr =| DCRQS; else addr->dctcsr =& ~DCRQS; } PS->integ = sps; return(status); } /* * Read a DC11 */ dcread(dev) { register struct tty *tp; tp = &dc11[dev.d_minor]; (*linesw[tp->t_discp].l_read)(tp); } /* * Write a DC11 */ dcwrite(dev) { register struct tty *tp; tp = &dc11[dev.d_minor]; (*linesw[tp->t_discp].l_write)(tp); } /* * DC11 transmitter interrupt. */ dcxint(dev) { register struct tty *tp; ttstart(tp = &dc11[dev.d_minor]); } /* * DC11 receiver interrupt. */ dcrint(dev) { register struct tty *tp; register int c, rcsr; int tcsr; int status, action; tp = &dc11[dev.d_minor]; rcsr = tp->t_addr->dcrcsr; if(rcsr&MTRANS) { /* * Only primary carrier transitions cause interrupts */ tcsr = tp->t_addr->dctcsr; status = (rcsr&CARRIER)|(tcsr&CTS)|((tcsr>>15)&SR); action = (*linesw[tp->t_discp].l_mt)(tp, status); if (action > 0) dcmctl(dev, action); if ((rcsr = tp->t_addr->dcrcsr)&DONE == 0) return; } c = tp->t_addr->dcrbuf; if(rcsr&DCOVRN) c =| OVERRUN; else { rcsr =& PARITY; if (tp->t_flags&RAW == 0) if(rcsr && (tp->t_flags&ODDP)==0 || !rcsr && (tp->t_flags&EVENP)==0) c =| PERROR; } (*linesw[tp->t_discp].l_rcvd)(c, tp); } /* * DC11 stty/gtty. * Perform general functions and set speeds. */ dcsgtty(dev, flag) { register struct tty *tp; tp = &dc11[dev.d_minor]; ttioctl(dev, tp, flag); } 0) dcmctl(dev, action); if ((rcsr = tp->t_addr->dcrcsr)&DONE == 0) return; } c = tp->t_addr->dcrbuf; if(rcsr&DCOVRN) c =| OVERRUN; else { rcsr =& PARITY; if (tp->t_flags&RAW == 0) if(rcsr && (tp->t_flags&ODDP)==0 || !rcsr && (tp->t_flags&EVENP)==0) c =| PERROR; } (*linesw[tp->t_discp].l_rcvd)(c, tp); } /* * DC11 stty/gtty. * Perform general functions and set speeds. */ dcsgtty(dev, flag) { register struct tty *tp; tp = &dc11[dev.d_mi# /* */ /* * DH-11 driver * This driver calls on the DHDM driver. * If the DH has no DM11-BB, then the latter will * be fake. To insure loading of the correct DM code, * lib2 should have dhdm.o, dh.o and dhfdm.o in that order. */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" #define DHADDR 0160020 #define DHTYPE 03 #define NDH11 (1*16) /* number of lines */ #define DHNCH 8 /* max number of DMA chars */ struct tty dh11[NDH11]; /* * Place from which to do DMA on output */ char dh_clist[NDH11][DHNCH]; /* * Used to communicate the number of lines to the DM */ int ndh11 {NDH11}; /* * Hardware control bits */ #define BITS6 01 #define BITS7 02 #define BITS8 03 #define TWOSB 04 #define PENABLE 020 /* DEC manuals incorrectly say this bit causes generation of even parity. */ #define OPAR 040 #define HDUPLX 040000 #define IENABLE 030100 #define XINT 0100000 /* * Software copy of last dhbar */ int dhsar[NDH11/16]; struct dhregs { int dhcsr; int dhnxch; int dhlpr; int dhcar; int dhbcr; int dhbar; int dhbreak; int dhsilo; }; /* * Open a DH11 line. */ dhopen(dev, flag) { register struct tty *tp; register minor, dhaddr; extern dhstart(); if ((minor = dev.d_minor & 0377) >= NDH11) { u.u_error = ENXIO; return; } dhaddr = DHADDR + (minor>>4)*16; tp = &dh11[minor]; tp->t_addr = dhstart; tp->t_dev = dev; tp->t_dtype = DHTYPE; tp->t_state =| SSTART; if (flag) { dhaddr->dhcsr =| IENABLE; (*linesw[tp->t_discp].l_open)(dev, tp); } } /* * Close a DH11 line. */ dhclose(dev, flag) { register struct tty *tp; tp = &dh11[dev.d_minor & 0377]; (*linesw[tp->t_discp].l_close)(dev, tp); } /* * Read from a DH11 line. */ dhread(dev) { register struct tty *tp; tp = &dh11[dev.d_minor & 0377]; (*linesw[tp->t_discp].l_read)(tp); } /* * write on a DH11 line */ dhwrite(dev) { register struct tty *tp; tp = &dh11[dev.d_minor & 0377]; (*linesw[tp->t_discp].l_write)(tp); } /* * DH11 receiver interrupt. */ dhrint(dev) { register struct tty *tp; register int c, dhaddr; dhaddr = DHADDR + (dev*16); while ((c = dhaddr->dhnxch) < 0) { /* char. present */ tp = &dh11[((c>>8)&017) + dev*16]; if (tp >= &dh11[NDH11]) continue; c =& (0377|PERROR|FRERROR); (*linesw[tp->t_discp].l_rcvd)(c, tp); } } /* * stty/gtty for DH11 */ dhsgtty(dev, flag) { register struct tty *tp; register minor; minor = dev.d_minor & 0377; tp = &dh11[minor]; ttioctl(dev, tp, flag); } /* * Set parameters from open or stty into the DH hardware * registers. */ dhparam(dev, atp) struct tty *atp; { register struct tty *tp; register int lpr, dhaddr; int minor, sps; minor = dev.d_minor & 0377; dhaddr = DHADDR + (minor>>4)*16; tp = atp; sps = PS->integ; spl5(); dhaddr->dhcsr.lobyte = (minor & 017) | IENABLE; lpr = (tp->t_speeds.hibyte<<10) | (tp->t_speeds.lobyte<<6); if (tp->t_speeds.lobyte == 4) /* 134.5 baud */ lpr =| BITS6|PENABLE|HDUPLX; else if (tp->t_flags&RAW || (tp->t_flags&(ODDP|EVENP))==(ODDP|EVENP)) lpr =| BITS8; else lpr =| BITS7|PENABLE; if ((tp->t_flags&EVENP)==0) lpr =| OPAR; if (tp->t_speeds.lobyte == 3) /* 110 baud */ lpr =| TWOSB; if(tp->t_flags&HDUP) lpr =| HDUPLX; dhaddr->dhlpr = lpr; PS->integ = sps; } /* * DH11 transmitter interrupt. * Restart each line which used to be active but has * terminated transmission since the last interrupt. */ dhxint(dev) { register struct tty *tp; register ttybit, bar; int dhaddr; dhaddr = DHADDR + (dev*16); bar = dhsar[dev] & ~dhaddr->dhbar; dhaddr->dhcsr =& ~XINT; ttybit = 1; for (tp = &dh11[dev*16]; bar; tp++) { if(bar&ttybit) { dhsar[dev] =& ~ttybit; bar =& ~ttybit; tp->t_state =& ~BUSY; dhstart(tp); } ttybit =<< 1; } } /* * Start (restart) transmission on the given DH11 line. */ dhstart(atp) struct tty *atp; { extern ttrstrt(); register c, nch; register struct tty *tp; int sps, dev, dhaddr; char *cp; sps = PS->integ; spl5(); tp = atp; dev = tp-dh11; dhaddr = DHADDR + (dev>>4)*16; /* * If it's currently active, or delaying, * no need to do anything. */ if (tp->t_state&(TIMEOUT|BUSY)) goto out; /* * t_char is a delay indicator which may have been * left over from the last start. * Arrange for the delay. */ if (c = tp->t_char) { tp->t_char = 0; timeout(ttrstrt, tp, (c&0177)+6); tp->t_state =| TIMEOUT; goto out; } cp = dh_clist[dev.d_minor & 0377]; nch = 0; /* * Copy DHNCH characters, or up to a delay indicator, * to the DMA area. */ while (nch > -DHNCH && (c = (*linesw[tp->t_discp].l_xmtd)(tp))) { if (c & CTOUT) { tp->t_char = c & 0377; break; } *cp++ = c & 0377; nch--; } /* * If any characters were set up, start transmission; * otherwise, check for possible delay. */ if (nch) { dhaddr->dhcsr.lobyte = (dev.d_minor & 017) | IENABLE; dhaddr->dhcar = cp+nch; dhaddr->dhbcr = nch; c = 1<<(dev.d_minor & 017); dhaddr->dhbar =| c; dhsar[dev>>4] =| c; tp->t_state =| BUSY; } else if (c = tp->t_char) { tp->t_char = 0; timeout(ttrstrt, tp, (c&0177)+6); tp->t_state =| TIMEOUT; } out: PS->integ = sps; } 377; break; } *cp++ = c & 0377; nch--; } /* * If any characters were set up, start transmission; * otherwise, check for possible delay. */ if (nch) { dhaddr->dhcsr.lobyte = (dev.d_minor & 017) | IENABLE; dhaddr->dhcar = cp+nch; dhaddr->dhbcr = nch; c = 1<<(dev.d_minor & 017); dhaddr->dhbar =| c; dhsar[dev>>4] =| c; tp->t_state =| BUSY; } else if (c = tp->t_char) { tp->t_char = 0; timeout(t# /* */ /* * DM-BB driver */ #include "../head/param.h" #include "../head/tty.h" #include "../head/conf.h" #define DMADDR 0170500 struct tty dh11[]; int ndh11; /* Set by dh.c to number of lines */ #define IENABLE 0100 /* interrupt enable */ #define DMBUSY 020 /* dm cycling */ #define SCENABL 040 #define TURNOFF 1 /* line enable only */ struct dmregs { int dmcsr; int dmlstat; int dmfill1; int dmfill2; }; /* * Fetch and set modem control status. * Accessed via switch on ctlsw table in conf.c */ dhmctl(dev, action) { register svcsr; register minor, dmaddr; int sps, status; minor = dev.d_minor & 0377; dmaddr = DMADDR + (minor>>4)*8; sps = PS->integ; spl5(); while((svcsr = dmaddr->dmcsr)&DMBUSY) dmaddr->dmcsr =& ~SCENABL; dmaddr->dmcsr = minor & 017; if (action == FSTATUS) status = (dmaddr->dmlstat>>4)&07; else { dmaddr->dmlstat = dmbits(action); status = 0; } dmaddr->dmcsr = svcsr|(IENABLE|SCENABL); PS->integ = sps; return(status); } /* * DM11 interrupt. Pass modem status to line discipline routine. * Implement specified action. */ dmint(dev) { register struct tty *tp; register action, dmaddr; int status; dmaddr = DMADDR + (dev*8); if (dmaddr->dmcsr&DONE) { tp = &dh11[(dev<<4) + (dmaddr->dmcsr&017)]; dmaddr->dmcsr =& ~(DONE|SCENABL); if (tp < &dh11[ndh11]) { status = (dmaddr->dmlstat>>4)&07; action = (*linesw[tp->t_discp].l_mt)(tp, status); if (action != 0) dmaddr->dmlstat = dmbits(action); } dmaddr->dmcsr =| SCENABL; } } /* * Translate specified action into bits for dm line status register */ dmbits(action) { register lstat; switch(action&03) { case DISABLE: lstat = 0; break; case HUP: lstat = TURNOFF; break; case TURNON: /* * Set enable and data terminal ready. Set primary and secondary * carrier status according to bits 2 and 3 of "action" */ lstat = action; } return(lstat); } ].l_mt)(tp, status); if (action != 0) dmaddr->dmlstat = dmbits(action); } dmaddr->dmcsr =| SCENABL; } } /* * Translate sp# /* */ /* * DM-BB fake driver */ #include "../head/tty.h" #include "../head/conf.h" struct tty dh11[]; dhmctl(dev, action) { if (action = FSTATUS) return(CARRIER|CTS); } break; case TURNON: /* * Set enable and data terminal ready. Set primary and secondary * carrier status according to bits 2 and 3 of "action" */ lstat = action; } return(lstat); } ].l_mt)(tp, status); if (action != 0) dmaddr->dmlstat = dmbits(action); } dmaddr->dmcsr =| SCENABL; } } /* * Translate sp# /* * DN-11 ACU interface */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" struct { struct dnreg { int dn_reg; } dnline[][4]; }; /* * This structure overlays the dnreg structure * dn_stat is unreferenced * dn_datum used to output the next digit to be dialed */ struct { char dn_stat; char dn_datum; }; int ndn11 4; /*number of dn11s...multiple of 4 */ #define DNADDR 0175200 #define DN0MOD4 ~3 #define PWI 0100000 #define ACR 040000 #define DLO 010000 #define DONE 0200 #define IENABLE 0100 #define DSS 040 #define PND 020 #define MENABLE 04 #define DPR 02 #define CRQ 01 #define DNPRI 5 dnopen(dev, flag) { register struct dnreg *dnadr; register int dn; dn = dev.d_minor; dnadr = DNADDR->dnline[0] + dn; if (dn >= ndn11 || dnadr->dn_reg&(PWI|DLO)) u.u_error = ENXIO; else { (dnadr&DN0MOD4)->dn_reg =| MENABLE; dnadr->dn_reg = IENABLE|MENABLE|CRQ; } } dnclose(dev) { DNADDR->dnline[0][dev.d_minor].dn_reg =& MENABLE; } dnwrite(dev) { register struct dnreg *dnadr; register c; extern lbolt; dnadr = DNADDR->dnline[0] + dev.d_minor; while((dnadr->dn_reg & (PWI|ACR|DSS)) == 0) { if((dnadr->dn_reg&PND) == 0 || u.u_count == 0 || (c=cpass()) < 0) sleep(dnadr,DNPRI); else if(c == '-') { sleep(&lbolt,DNPRI); sleep(&lbolt,DNPRI); } else { dnadr->dn_datum = c; dnadr->dn_reg =| DPR; sleep(dnadr,DNPRI); } } if(dnadr->dn_reg&(PWI|ACR)) u.u_error = EIO; } dnint(dev) { register struct dnreg *dnadr; register count; dnadr = DNADDR->dnline[dev.d_minor]; (dnadr&DN0MOD4)->dn_reg =& ~(MENABLE); (dnadr&DN0MOD4)->dn_reg =| MENABLE; count = 4; do { if(dnadr->dn_reg & DONE) { dnadr->dn_reg =& ~(DONE); wakeup(dnadr); } } while(dnadr++, --count); } e if(c == '-') { sleep(&lbolt,DNPRI); sleep(&lbolt,DNPRI); } else { dnadr->dn_datum = c; dnadr->dn_reg =| DPR; sleep(dnadr,DNPRI); } } if(dnadr->dn_reg&(PWI|ACR)) u.u_error = EIO; } dnint(dev) { register struct dnreg *dnadr; re# /* * Copyright 1973 Bell Telephone Laboratories Inc */ /* * DP-11 Synchronous interface driver * This driver is rather insensitive to the remote * device it talks to, which is to say most of the protocol * must be supplied by the calling program. * Exceptions: parity is even; 7 data bits per character; * max. of 512 characters per record; 10 second timeout * on waiting to receive; half-duplex transmission. */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/buf.h" #include "../head/bufx.h" /* control info */ struct { char *dp_buf; char *dp_bufp; int dp_nxmit; char dp_state; char dp_timer; int dp_proc; } dp11; /* device registers */ struct { int dprcsr; char dprbuf; char dpsyn0; int dptcsr; char dptbuf; char dpsyn1; }; /* bits */ #define ODDPAR 010000 #define IENABLE 0100 #define HDUPLX 02 #define CTRANS 0100000 #define RORUN 040000 #define RING 020000 #define DSRDY 010000 #define CARRIER 04000 #define DONE 0200 #define IENABLE 0100 #define SIENABL 040 #define WRITE 1 #define READ 0 #define DTRDY 01 #define RCVACT 04000 #define DPADDR 0174770 #define DPPRI 5 /* * The open fails unless the device is not open or * the opening process is the one that has it open already. */ dpopen(dev, flag) { int dptimeout(); if (dp11.dp_proc!=0 && dp11.dp_proc!=u.u_procp) { u.u_error = ENXIO; return; } dp11.dp_proc = u.u_procp; dp11.dp_state = READ; if (dp11.dp_buf==0) { dp11.dp_buf = getblk(NODEV); dp11.dp_bufp = dp11.dp_buf->b_addr; dp11.dp_timer = 60; timeout(dptimeout, 0, 60); } DPADDR->dpsyn0 = 026; DPADDR->dprcsr = HDUPLX|IENABLE; DPADDR->dptcsr = IENABLE|SIENABL|DTRDY; } dpclose() { DPADDR->dprcsr = 0; DPADDR->dptcsr = 0; dp11.dp_timer = 0; dp11.dp_proc = 0; if (dp11.dp_buf != 0) { brelse(dp11.dp_buf); dp11.dp_buf = 0; } } /* * Read waits until: * there is loss of "data set ready", or * a timeout occurs, or * a full record has been received. * The former two result in an error. */ dpread() { register char *bp, **epp; bp = dp11.dp_buf->b_addr; epp = &dp11.dp_bufp; for(;;) { if(dpwait()) return; if (*epp > bp) break; spl6(); if (dp11.dp_timer <= 1) { spl0(); return; } sleep(&dp11, DPPRI); spl0(); } iomove(dp11.dp_buf, 0, min(u.u_count, *epp-bp), B_READ); } /* * write checks to make sure that the data set is not reading, * and that it is ready. Then the record is copied * and transmission started. */ dpwrite() { register char *bp; if (u.u_count==0 ||dpwait()) return; dp11.dp_state = WRITE; bp = dp11.dp_buf->b_addr; dp11.dp_bufp = bp; if (u.u_count>512) u.u_count = 512; dp11.dp_nxmit = u.u_count; iomove(dp11.dp_buf, 0, u.u_count, B_WRITE); dpstart(); } /* * If "data set ready" is down return an error; otherwise * wait until the dataset is in read state with no carrier, * which means a record has just been received. */ dpwait() { for(;;) { if ((DPADDR->dptcsr&DSRDY)==0 || dp11.dp_buf==0) { u.u_error = EIO; return(1); } spl6(); if (dp11.dp_state==READ && (DPADDR->dptcsr&CARRIER)==0) { spl0(); return(0); } sleep(&dp11, DPPRI); spl0(); } } /* * Start off the next character to be transmitted; * when the record is done, drop back into read state. */ dpstart() { register int c; extern char partab[]; dp11.dp_timer = 5; if (--dp11.dp_nxmit >= 0) { c = (*dp11.dp_bufp++) & 0177; DPADDR->dptbuf = c | ~partab[c]&0200; } else { dp11.dp_bufp = dp11.dp_buf->b_addr; dp11.dp_state = READ; } } /* * Count down the DP timer (once per second) * If it runs out, it presumably means the other station * won't speak. */ dptimeout() { if (dp11.dp_timer==0) return; if (--dp11.dp_timer==0) { dpturnaround(); dp11.dp_timer = 1; } timeout(dptimeout, 0, 60); } /* * Receiver interrupt: if reading, stash character * unless there is an overrun. */ dprint() { register int c; c = DPADDR->dprbuf & 0177; if (dp11.dp_state==READ) { if ((DPADDR->dprcsr&ODDPAR) == 0) c =| 0200; if (dp11.dp_bufp < dp11.dp_buf->b_addr+512) *dp11.dp_bufp++ = c; } } /* * Transmitter interrupt: * Knock down hardware bits. * If carrier has dropped, the record is done, so turn the line around; * otherwise start another character. */ dpxint() { register int dpstat; dpstat = DPADDR->dptcsr; DPADDR->dptcsr =& ~(CTRANS|RORUN|RING|DONE); if (dpstat & (CTRANS|RORUN)) dpturnaround(); else if (dpstat&DONE && dp11.dp_state==WRITE) dpstart(); } /* * Change the state from writing to reading at the end of a record. */ dpturnaround() { dp11.dp_timer = 5; DPADDR->dprcsr =& ~RCVACT; if (dp11.dp_state==WRITE) { dp11.dp_state = READ; dp11.dp_bufp = dp11.dp_buf->b_addr; } wakeup(&dp11); } * otherwise start another character. */ dpxint() { register int dpstat; dpstat = DPADDR->dptcsr; DPADDR->dptcsr =& ~(CTRANS|RORUN|RING|DONE); if (dpstat & (CTRANS|RORUN)) dpturnaround(); else if (dpstat&DONE && dp11.dp_state==WRITE) dpstart(); } /* * Change the state from writing to reading at the end of a re# /* * RP04 disk driver */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" #define NSECT 22 /* 22 sectors per track */ #define NTRACK 19 #define NCYL NSECT*NTRACK /* 418 sectors per cylinder */ struct hpregs { int hpcs1; /* Control and Status register 1 */ int hpwc; /* Word count register */ int hpba; /* UNIBUS address register */ int hpda; /* Desired address register */ int hpcs2; /* Control and Status register 2*/ int hpds; /* Drive Status */ int hper1; /* Error register 1 */ int hpas; /* Attention Summary */ int hpla; /* Look ahead */ int hpdb; /* Data buffer */ int hpmr; /* Maintenance register */ int hpdt; /* Drive type */ int hpsn; /* Serial number */ int hpof; /* Offset register */ int hpdc; /* Desired Cylinder address register*/ int hpcc; /* Current Cylinder */ int hper2; /* Error register 2 */ int hper3; /* Error register 3 */ int hpec1; /* Burst error bit position */ int hpec2; /* Burst error bit pattern */ int hpbae; /* Bus address extension */ int hpcs3; /* Control and status register 3 */ }; #define HPADDR 0176700 #define NHP 2 struct { char *nblocks; int cyloff; } hp_sizes[] { 23*NCYL, 0, /* 0: cyl 0 thru 22 incl. */ /* cyl 23 thru 43 incl. unused */ 65535l, 44, /* 1: cyl 44 thru 200 incl. (158) */ 65535l, 201, /* 2: cyl 201 thru 357 incl. */ 50*NCYL, 358, /* 3: cyl 358 thru 407 incl. */ /* cyl 408 thru 410 incl. unused */ 100*NCYL, 0, /* 4: cyl 0 thru 99 incl. */ 100*NCYL, 100, /* 5: cyl 100 thru 199 incl. */ 99*NCYL, 201, /* 6: cyl 201 thru 299 incl. */ 100*NCYL, 300, /* 7: cyl 300 thru 399 incl. */ 44*NCYL, 0, /* 8: cyl 0 thru 43 incl. */ 65535l, 44, /* 9: cyl 44 thru 201 incl.(158) */ 65535l, 202, /* 10: cyl 202 thru 359 incl.(158) */ 48*NCYL, 360, /* 11: cyl 360 thru 407 incl. */ 65535l, 408, /* 12: cyl 408 thru 565 incl.(158) */ 65535l, 566, /* 13: cyl 566 thru 723 incl.(158) */ 89*NCYL, 724, /* 14: cyl 724 thru 812 incl. */ /* cyl 813 thru 814 spare */ 79*NCYL, 44, /* 15: cyl 44 thru 122 incl. */ 79*NCYL, 123, /* 16: cyl 123 thru 201 incl. */ 79*NCYL, 202, /* 17: cyl 202 thru 280 incl. */ 79*NCYL, 281, /* 18: cyl 281 thru 359 incl. */ /* cyl 360 thru 379 spare */ 28*NCYL, 380, /* 19: cyl 380 thru 407 incl. */ 79*NCYL, 408, /* 20: cyl 408 thru 486 incl. */ 79*NCYL, 487, /* 21: cyl 487 thru 565 incl. */ 79*NCYL, 566, /* 22: cyl 566 thru 644 incl. */ 79*NCYL, 645, /* 23: cyl 645 thru 723 incl. */ /* Negative Filesystems */ /* Backward version of first 8 filsys */ NCYL*23, -22, /* 24: cyl 0 thru 23 incl. rev. */ /* cyl 24 thru 43 incl. unused */ 65535l, -200, /* 25: cyl 44 thru 200 incl. (158) */ 65535l, -357, /* 26: cyl 201 thru 357 incl. (158) */ 50*NCYL, -407, /* 27: cyl 358 thru 407 incl. rev. */ /* cyl 408 thru 410 incl. unused */ 100*NCYL, -99, /* 28: cyl 0 thru 99 incl. rev. */ 100*NCYL, -199, /* 29: cyl 100 thru 199 incl. rev. */ 99*NCYL, -299, /* 30: cyl 201 thru 299 incl. rev. */ 100*NCYL, -399, /* 31: cyl 300 thru 399 incl. rev. */ }; /* * NOTE: THE SWAP AREA MAY NOT BE ON AN INVERTED DISK AREA */ struct devtab hptab; struct buf rhpbuf; struct iostat hpstat[NHP]; struct errtab hpetab { etabinit(E_BLK|E_RH70,NHP,HP,hpstat) }; /* Drive Commands */ #define GO 01 #define PRESET 020 #define RECAL 06 #define RCLR 010 #define VV 0100 #define OFFSET 014 #define READY 0200 /* hpds - drive ready */ #define PIP 020000 /* hpds - Positioning Operation in Progress */ #define ERR 040000 /* hpcs1 - composite error */ #define DU 040000 /* hper1 - Drive Unsafe */ #define DTE 010000 /* hper1 - Drive Timing Error */ #define OPI 020000 /* hper1 - Operation Incomplete */ /* Error Correction Code errors */ #define DCK 0100000 /* hper1 - Data Check error */ #define ECH 0100 /* hper1 - ECC hard error */ #define CLR 040 /* hpcs2 - Controller Clear */ #define FMT22 010000 /* hpof - 16 bit /word format */ /* * Use av_back to save track+sector, * b_resid for cylinder. */ #define trksec av_back #define cylin b_resid #define DK_N 2 hpopen(dev, flag) { if(dev.d_minor >= (NHP<<5)) u.u_error = ENXIO; } hpstrategy(abp) struct buf *abp; { register struct buf *bp; register char *p1, *p2; char *p3; bp = abp; p3 = p1 = &hp_sizes[bp->b_dev.d_minor&037]; if(bp->b_blkno >= p1->nblocks){ if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else{ bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = 0; bp->cylin = p1->cyloff; p1 = bp->b_blkno; p2 = lrem(p1, 22); p1 = ldiv(p1, 22); bp->trksec = (p1%19)<<8 | p2; bp->cylin =+ p1/19; if(p3->cyloff < 0){ bp->cylin = -bp->cylin; } spl5(); if ((p1 = hptab.d_actf)==0) hptab.d_actf = bp; else { for (; p2 = p1->av_forw; p1 = p2) { if (p1->cylin <= bp->cylin && bp->cylin < p2->cylin || p1->cylin >= bp->cylin && bp->cylin > p2->cylin) break; } bp->av_forw = p2; p1->av_forw = bp; } if (hptab.d_active==0) hpstart(); spl0(); } hpstart() { register struct buf *bp; register unit; if ((bp = hptab.d_actf) == 0) return; hptab.d_active++; unit = (bp->b_dev.d_minor>>5)&07; HPADDR->hpcs2 = unit; hpetab.e_aunit = &hpstat[unit]; if((HPADDR->hpds&VV) == 0) { HPADDR -> hpcs1 = PRESET | GO; HPADDR -> hpof = FMT22; hpetab.e_aunit->io_misc++; } hpetab.e_aunit->io_ops++; blkacty =| (1<hpdc = bp->cylin; rhstart(bp, &HPADDR->hpda, bp->trksec, &HPADDR->hpbae); dk_busy =| 1<b_wcount>>5) & 03777; } hpintr() { register struct buf *bp; struct hpregs hpregs[0]; int ctr; if (hptab.d_active == 0) return; bp = hptab.d_actf; hptab.d_active = 0; blkacty =& ~(1<hpcs1 & ERR) { /* error bit */ /* deverror(bp, HPADDR->hpcs2);/**/ fmtblk(&hpetab,HPADDR,sizeof(hpregs[0])/2,bp); if(HPADDR->hper1 & (DU|DTE|OPI)) { HPADDR->hpcs2 = CLR; HPADDR->hpcs1 = RECAL|GO; hpetab.e_aunit->io_misc++; ctr = 0; while ((HPADDR->hpds&PIP) && --ctr); } HPADDR->hpcs1 = RCLR|GO; if (hptab.d_errcnt < 10) { if(hptab.d_errcnt++ == 0) logerr(&hpetab,E_FIRST); hpstart(); return; } bp->b_flags =| B_ERROR; } if(hpetab.e_emsg != NULL) logerr(&hpetab,E_RETRY); hptab.d_errcnt = 0; hptab.d_actf = bp->av_forw; bp->b_resid = HPADDR->hpwc; iodone(bp); hpstart(); } hpread(dev) { register nblks; register char *p1;  p1 = &hp_sizes[dev.d_minor&037]; nblks = p1->nblocks; if(p1->cyloff<0){ if(negcyl(hpstrategy, &rhpbuf, dev, B_READ, nblks, NCYL)) return; if(u.u_error) return; } physio(hpstrategy, &rhpbuf, dev, B_READ, nblks); } hpwrite(dev) { register nblks; register char *p1; p1 = &hp_sizes[dev.d_minor&037]; nblks = p1->nblocks; if(p1->cyloff<0){ if(negcyl(hpstrategy, &rhpbuf, dev, B_WRITE, nblks, NCYL)) return; if(u.u_error) return; } physio(hpstrategy, &rhpbuf, dev, B_WRITE, nblks); } p1 = &hp_sizes[dev.d_minor&037]; nblks = p1->nblocks; if(p1->cyloff<0){ if(negcyl(hpstrategy, &rhpbuf, dev, B_READ, nblks, NCYL)) return; if(u.u_error) return; } physio(hpstrategy, &rhpbuf, dev, B_READ, nblks); } hpwrite(dev) { register nblks; register char *p1; p1 = &hp_sizes[dev.d_minor&037]; nblks = p1->nblocks; if(p1->cyloff<0){ if(negcyl(hpstrategy, &rhpbuf, dev, B_WRITE, nblks, NCYL)) return; if(u.u_error) return; } physio(hpstrategy, &rhpbuf, dev, B_WRITE, nblks); }# /* * RS03/04 disk driver */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" struct hsregs { int hscs1; /* Control and Status register 1 */ int hswc; /* Word count register */ int hsba; /* UNIBUS address register */ int hsda; /* Desired address register */ int hscs2; /* Control and Status register 2 */ int hsds; /* Drive Status */ int hser; /* Error register */ int hsas; /* not used */ int hsla; /* not used */ int hsdb; /* not used */ int hsmr; /* not used */ int hsdt; /* not used */ int hsbae; /* 11/70 bus extension */ int hscs3; /* 11/70 Control and status register 3 */ }; #define NHS 1 #define HSADDR 0172040 struct devtab hstab; struct buf rhsbuf; struct iostat hsstat[NHS]; struct errtab hsetab { etabinit(E_BLK|E_RH70,NHS,HS,hsstat) }; #define ERR 040000 /* hscs1 - composite error */ #define GO 01 #define RCLR 010 #define DRY 0200 /* hsds - Drive Ready */ #define DK_N 0 hsopen(dev, flag) { if((dev.d_minor&07) >= NHS) u.u_error = ENXIO; } hsstrategy(abp) struct buf *abp; { register struct buf *bp; register mblks; bp = abp; mblks = 1024; /* RJS03 */ if(bp->b_dev.d_minor >= 8) mblks = 2048; /* RJS04 */ if(bp->b_blkno >= mblks) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = 0; spl5(); if (hstab.d_actf==0) hstab.d_actf = bp; else hstab.d_actl->av_forw = bp; hstab.d_actl = bp; if (hstab.d_active==0) hsstart(); spl0(); } hsstart() { register struct buf *bp; register addr, minor; if ((bp = hstab.d_actf) == 0) return; hstab.d_active++; addr = bp->b_blkno; if((minor = bp->b_dev.d_minor) < 8) addr =<< 1; /* RJS03 */ minor =& 07; hsetab.e_aunit = &hsstat[minor]; hsetab.e_aunit->io_ops++; blkacty =| (1<hscs2 = minor; rhstart(bp, &HSADDR->hsda, addr<<1, &HSADDR->hsbae); dk_busy =| 1<b_wcount>>5) & 03777; } hsintr() { register struct buf *bp; struct hsregs hsregs[0]; if (hstab.d_active == 0) return; bp = hstab.d_actf; blkacty =& ~(1<hscs1 & ERR){ /* error bit */ /* deverror(bp, HSADDR->hscs2, 0);/**/ fmtblk(&hsetab,HSADDR,sizeof(hsregs[0])/2,bp); HSADDR->hscs1 = RCLR|GO; hsetab.e_aunit->io_misc++; if (hstab.d_errcnt < 10) { if(hstab.d_errcnt++ == 0) logerr(&hsetab,E_FIRST); hsstart(); return; } bp->b_flags =| B_ERROR; } if(hsetab.e_emsg != NULL) logerr(&hsetab,E_RETRY); hstab.d_errcnt = 0; hstab.d_actf = bp->av_forw; bp->b_resid = HSADDR->hswc; iodone(bp); hsstart(); } hsread(dev) { physio(hsstrategy, &rhsbuf, dev, B_READ, dev.d_minor >= 8 ? 2048 : 1024); } hswrite(dev) { physio(hsstrategy, &rhsbuf, dev, B_WRITE, dev.d_minor >= 8 ? 2048 : 1024); } it->io_misc++; if (hstab.d_errcnt < 10) { if(hstab.d_err# /* * TU16 Tape Driver * * Handles one TM02 controller, up to 4 TU16 slave transports * minor device classes: * bits 0,1: slave select * bit 2 off: rewind on close; on: position after first TM * bit 3 off: 800 bpi; on: 1600 bpi */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/file.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" #define NHT 4 #define HTADDR 0172440 struct htregs { int htcs1, htwc, htba, htfc; int htcs2, htds, hter, htas; int htck, htdb, htmr, htdt; int htsn, httc, htbae, htcs3; }; struct devtab httab; struct buf rhtbuf, chtbuf; struct iostat htstat[NHT]; struct errtab htetab { etabinit(E_BLK|E_RH70,NHT,HT,htstat) }; char h_openf[NHT]; int h_den[NHT]; char *h_blkno[NHT], *h_nxrec[NHT]; #define GO 01 #define NOP 0 #define WEOF 026 #define SFORW 030 #define SREV 032 #define ERASE 024 #define REW 06 #define DCLR 010 #define P800 01300 /* 800 + pdp11 mode */ #define P1600 02300 /* 1600 + pdp11 mode */ #define IENABLE 0100 #define RDY 0200 #define TMARK 04 #define DRY 0200 #define EOT 02000 #define CS 02000 #define COR 0100000 #define PES 040 #define WRL 04000 #define MOL 010000 #define PIP 020000 #define ERR 040000 #define FCE 01000 #define TRE 040000 #define HARD 064023 /* UNS|OPI|NEF|FMT|RMR|ILR|ILF */ #define SSEEK 1 #define SIO 2 #define SABORT 3 #define SRETRY 4 #define SCOM 5 #define SOK 6 #define SERR 7 htopen(dev, flag) { register unit, ds, i; unit = dev&03; if (unit >= NHT || h_openf[unit]) { u.u_error = ENXIO; return; } h_den[unit] = (dev&010 ? P1600 : P800)|unit; flag =& FWRITE; for(i = 0; i < 75; i++) { /* max 5 min wait on rewind */ h_blkno[unit] = 0; h_nxrec[unit] = -1; ds = hcommand(unit, NOP); if ((ds&MOL)==0 || (flag && (ds&WRL)) || h_openf[unit]) { u.u_error = ENXIO; return; } if((ds&PIP)==0) { if (u.u_error==0) h_openf[unit]++; return; } sleep(&lbolt,-1); } u.u_error = ENXIO; } htclose(dev, flag) { register int unit; unit = dev&03; flag =& FWRITE; if (flag) { hcommand(unit, WEOF); hcommand(unit, WEOF); } if (dev&04) { if (flag) hcommand(unit, SREV); else hcommand(unit, NOP); } else hcommand(unit, REW); h_openf[unit] = 0; } hcommand(unit, com) { register struct buf *bp; bp = &chtbuf; spl5(); while(bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED; sleep(bp, PRIBIO); } spl0(); bp->b_dev = unit; bp->b_resid = com; bp->b_blkno = 0; bp->b_flags = B_BUSY|B_READ; htstrategy(bp); iowait(bp); if(bp->b_flags&B_WANTED) wakeup(bp); bp->b_flags = 0; return(bp->b_resid); } htstrategy(abp) struct buf *abp; { register struct buf *bp; register char **p; bp = abp; p = &h_nxrec[bp->b_dev&03]; if (*p < bp->b_blkno || (*p == bp->b_blkno && bp->b_flags&B_READ)) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } if ((bp->b_flags&B_READ)==0) *p = bp->b_blkno + 1; bp->av_forw = 0; spl5(); if (httab.d_actf==0) httab.d_actf = bp; else httab.d_actl->av_forw = bp; httab.d_actl = bp; if (httab.d_active==0) htstart(); spl0(); } htstart() { register struct buf *bp; register int unit; register char *blkno; loop: if ((bp = httab.d_actf) == 0) return; unit = bp->b_dev&03; HTADDR->htcs2 = 0; if((HTADDR->httc&03777)!=h_den[unit]) HTADDR->httc = h_den[unit]; blkno = h_blkno[unit]; if ((HTADDR->htds&MOL)==0) goto abort; htetab.e_aunit = &htstat[unit]; if (bp == &chtbuf) { if (bp->b_resid==NOP) { bp->b_resid = HTADDR->htds; goto next; } httab.d_active = SCOM; htetab.e_aunit->io_misc++; HTADDR->htfc = 0; HTADDR->htcs1 = bp->b_resid|IENABLE|GO; return; } if (h_openf[unit] < 0) goto abort; if (blkno == bp->b_blkno) { httab.d_active = SIO; htetab.e_aunit->io_ops++; blkacty =| (1<htfc, bp->b_wcount<<1, &HTADDR->htbae); } else { httab.d_active = SSEEK; htetab.e_aunit->io_misc++; if (blkno < bp->b_blkno) { HTADDR->htfc = blkno - bp->b_blkno; HTADDR->htcs1 = SFORW|IENABLE|GO; } else { HTADDR->htfc = bp->b_blkno - blkno; HTADDR->htcs1 = SREV|IENABLE|GO; } } return; abort: bp->b_flags =| B_ERROR; next: httab.d_actf = bp->av_forw; iodone(bp); goto loop; } htintr() { register struct buf *bp; register int unit, state; struct htregs htregs[0]; int err; if ((bp = httab.d_actf)==0) return; blkacty =& ~(1<b_dev&03; state = httab.d_active; httab.d_active = 0; if (HTADDR->htcs1&TRE) { err = HTADDR->hter; if (HTADDR->htcs2.hibyte>0 || err&HARD) state = SERR; if (bp == &rhtbuf) { err =& ~FCE; } if ((bp->b_flags&B_READ) && (HTADDR->htds&PES)) err =& ~(CS|COR); if(HTADDR->htds&EOT) { h_openf[unit] = -1; } else if(HTADDR->htds&TMARK) { state = 0; HTADDR->htwc = bp->b_wcount; if(bp != &rhtbuf) h_openf[unit] = -1; } else if(state != SERR && err == 0) state = SOK; else fmtblk(&htetab,HTADDR,sizeof(htregs[0])/2,bp); HTADDR->htcs1 = TRE|DCLR|GO; htetab.e_aunit->io_misc++; h_blkno[unit]++; if (state==SIO && httab.d_errcnt < 10) { if(httab.d_errcnt++ == 0) logerr(&htetab,E_FIRST); htetab.e_aunit->io_misc++; httab.d_active = SRETRY; HTADDR->htfc = -1; HTADDR->htcs1 = SREV|IENABLE|GO; return; } if (state!=SOK) { if(state) bp->b_flags =| B_ERROR; state = SABORT; } } else if (HTADDR->htcs1 < 0) { /* SC */ if (HTADDR->htds&ERR) { fmtblk(&htetab,HTADDR,sizeof(htregs[0])/2,bp); HTADDR->htcs1 = DCLR|GO; htetab.e_aunit->io_misc++; } } switch(state) { case SIO: case SOK: h_blkno[unit]++; case SABORT: case SCOM: if(htetab.e_emsg != NULL) logerr(&htetab,E_RETRY); httab.d_errcnt = 0; httab.d_actf = bp->av_forw; bp->b_resid = HTADDR->htwc; iodone(bp); break; case SRETRY: if((bp->b_flags&B_READ)==0) { htetab.e_aunit->io_misc++; httab.d_active = SSEEK; HTADDR->htcs1 = ERASE|IENABLE|GO; return; } case SSEEK: h_blkno[unit] = bp->b_blkno; break; default: return; } htstart(); } htread(dev) { htphys(dev); physio(htstrategy, &rhtbuf, dev, B_READ, 0); } htwrite(dev) { htphys(dev); physio(htstrategy, &rhtbuf, dev, B_WRITE, 0); } htphys(dev) { register unit, a; unit = dev&03; a = lshift(u.u_offset, -9); h_blkno[unit] = a; h_nxrec[unit] = ++a; } if((bp->b_flags&B_READ)==0) { htetab.e_aunit->io_misc++; httab.d_active = SSEEK; HTADDR->htcs1 = ERASE|IENABLE|GO; return; } case SSEEK: h_blkn# /* */ /* * KL/DL-11 driver */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" /* base address */ #define KLADDR 0177560 /* console */ #define KLBASE 0176500 /* kl and dl11-a */ #define DLBASE 0175610 /* dl-e */ #define KLTYPE 0 #define DLTYPE 01 /* dl-e */ #define NKL11 1 #define NDL11 0 #define RDRENB 01 #define IENABLE 0100 /* interrupt enable */ #define DTR 02 /* data teminal ready */ #define MENABLE 040 /* modem enable */ int nkl11 NKL11+NDL11; struct tty kl11[NKL11+NDL11]; struct klregs { int klrcsr; int klrbuf; int kltcsr; int kltbuf; } klopen(dev, flag) { register char *addr; register struct tty *tp; if(dev.d_minor >= NKL11+NDL11) { u.u_error = ENXIO; return; } tp = &kl11[dev.d_minor]; /* * set up minor 0 to address KLADDR * set up minor 1 thru NKL11-1 to address from KLBASE * set up minor NKL11 on to address from DLBASE */ addr = KLADDR + 8*dev.d_minor; tp->t_dtype = KLTYPE; if(dev.d_minor) addr =+ KLBASE-KLADDR-8; if(dev.d_minor >= NKL11) { addr =+ DLBASE-KLBASE-8*NKL11+8; tp->t_dtype = DLTYPE; } tp->t_addr = addr; tp->t_dev = dev; if (flag) { addr->klrcsr =| IENABLE|RDRENB; addr->kltcsr =| IENABLE; (*linesw[tp->t_discp].l_open)(dev, tp); } } klclose(dev, flag) { register struct tty *tp; tp = &kl11[dev.d_minor]; (*linesw[tp->t_discp].l_close)(dev, tp); } klread(dev) { register struct tty *tp; tp = &kl11[dev.d_minor]; (*linesw[tp->t_discp].l_read)(tp); } klwrite(dev) { register struct tty *tp; tp = &kl11[dev.d_minor]; (*linesw[tp->t_discp].l_write)(tp); } klsgtty(dev, flag) { register struct tty *tp; tp = &kl11[dev.d_minor]; ttioctl(dev, tp, flag); } klxint(dev) { register struct tty *tp; tp = &kl11[dev.d_minor]; ttstart(tp); } klrint(dev) { register int c, *addr; register struct tty *tp; int rcsr, status, action; tp = &kl11[dev.d_minor]; addr = tp->t_addr; while ((rcsr = addr->klrcsr)<0 || rcsr&DONE) { if(rcsr < 0) { /* * DL modem transition */ status = (rcsr>>10)&(CARRIER|SR)|(rcsr>>12)&CTS; action = (*linesw[tp->t_discp].l_mt)(tp, status); if(action > 0) dlmctl(dev, action); continue; } c = addr->klrbuf & (OVERRUN|FRERROR|PERROR|0377); addr->klrcsr =| RDRENB; (*linesw[tp->t_discp].l_rcvd)(c, tp); } } klmctl(dev, action) { if(action == FSTATUS) return(CARRIER|CTS); } dlmctl(dev, action) { struct tty *tp; register int sps, *addr; int rcsr, status; tp = &kl11[dev.d_minor]; addr = tp->t_addr; status = 0; sps = PS->integ; spl5(); switch(action&03) { case FSTATUS: rcsr = addr->klrcsr; status = (rcsr>>10)&(CARRIER|SR)|(rcsr>>12)&CTS; break; case DISABLE: addr->klrcsr =& ~(ST|RQS|DTR|MENABLE); break; case HUP: addr->klrcsr =& ~DTR; break; case TURNON: /* * Enable modem and set data terminal ready. Set primary and * secondary carrier according to bits 2 and 3 of "action" */ action =& (RQS|ST); addr->klrcsr = addr->klrcsr & ~(RQS|ST) | (action|DTR|MENABLE); }  PS->integ = sps; return(status); } l5(); switch(action&03) { case FSTATUS: rcsr = addr->klrcsr; status = (rcsr>>10)&(CARRIER|SR)|(rcsr>>12)&CTS; break; case DISABLE: addr->klrcsr =& ~(ST|RQS|DTR|MENABLE); break; case HUP: addr->klrcsr =& ~DTR; break; case TURNON: /* * Enable modem and set data terminal ready. Set primary and * secondary carrier according to bits 2 and 3 of "action" */ action =& (RQS|ST); addr->klrcsr = addr->klrcsr & ~(RQS|ST) | (action|DTR|MENABLE); } # /* */ /* * LP-11 Line printer driver */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #define LPADDR 0177514 #define IENABLE 0100 #define DONE 0200 #define LPPRI 10 #define LPLWAT 50 #define LPHWAT 100 #define EJLINE 60 #define MAXCOL 80 struct { int lpsr; int lpbuf; }; struct { int cc; int cf; int cl; int flag; int mcc; int ccc; int mlc; } lp11; #define CAP 00 /* Set to 0 for 96-char printer, else to 01 */ #define EJECT 02 #define OPEN 04 #define IND 000 /* Set to 0 for no indent, else to 010 */ #define FORM 014 lpopen(dev, flag) { if(lp11.flag & OPEN || LPADDR->lpsr < 0) { u.u_error = EIO; return; } lp11.flag =| (IND|EJECT|OPEN|CAP); LPADDR->lpsr =| IENABLE; lpcanon(FORM); } lpclose(dev, flag) { lpcanon(FORM); lp11.flag = 0; } lpwrite() { register int c; while ((c=cpass())>=0) lpcanon(c); } lpcanon(c) { register c1, c2; c1 = c; if(lp11.flag&CAP) { if(c1>='a' && c1<='z') c1 =+ 'A'-'a'; else switch(c1) { case '{': c2 = '('; goto esc; case '}': c2 = ')'; goto esc; case '`': c2 = '\''; goto esc; case '|': c2 = '!'; goto esc; case '~': c2 = '^'; esc: lpcanon(c2); lp11.ccc--; c1 = '-'; } } switch(c1) { case '\t': lp11.ccc = (lp11.ccc+8) & ~7; return; case FORM: case '\n': if((lp11.flag&EJECT) == 0 || lp11.mcc!=0 || lp11.mlc!=0) { lp11.mcc = 0; lp11.mlc++; if(lp11.mlc >= EJLINE && lp11.flag&EJECT) c1 = FORM; lpoutput(c1); if(c1 == FORM) lp11.mlc = 0; } case '\r': lp11.ccc = 0; if(lp11.flag&IND) lp11.ccc = 8; return; case 010: if(lp11.ccc > 0) lp11.ccc--; return; case ' ': lp11.ccc++; return; default: if(lp11.ccc < lp11.mcc) { lpoutput('\r'); lp11.mcc = 0; } if(lp11.ccc < MAXCOL) { while(lp11.ccc > lp11.mcc) { lpoutput(' '); lp11.mcc++; } lpoutput(c1); lp11.mcc++; } lp11.ccc++; } } lpstart() { register int c; while (LPADDR->lpsr&DONE && (c = getc(&lp11)) >= 0) LPADDR->lpbuf = c; } lpint() { lpstart(); if (lp11.cc == LPLWAT || lp11.cc == 0) wakeup(&lp11); } lpoutput(c) { if (lp11.cc >= LPHWAT) sleep(&lp11, LPPRI); putc(c, &lp11); spl4(); lpstart(); spl0(); } ccc < lp11.mcc) { lpoutput('\r'); lp11.mcc = 0; } if(lp11.ccc < MAXCOL) { while(lp11.ccc > lp11.mcc) { lpoutput(' '); lp11.mcc++; } lpoutput(c1); lp11.mcc++; } lp11.ccc++; } } lpstart() { register int c; while (LPADDR->lpsr&DONE && # /* * Copyright 1973 Bell Telephone Laboratories Inc */ #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/file.h" #include "../head/filex.h" #include "../head/reg.h" #include "../head/conf.h" #define DISCON 300 #define DLAY 10 #define DLAY1 30 #define M40STP 90 #define M40GO 30 #define QESC 037 #define QBRK 0 #define HSPEED 9 /* half-duplex state bits: t_lword */ #define LOCAL 01 #define PEVENT 02 #define CURSET 04 #define QDELIM 0200 #define WRTON 0400 #define CRLCHA 01000 #define TIMER1 02000 #define TIMER2 04000 #define EXTND 010000 #define ESCHA 020000 #define SNDRFLG 040000 #define SOLICIT 0100000 /* Indicates state of comm. channel: t_linest*/ #define QUIESNT 000 #define REC 001 #define INTRPT1 002 #define SEND 003 #define ERROR 004 #define RECHLD 005 #define SENDREQ 006 #define SENDSTP 007 #define INACT 010 #define INTRPT2 011 #define SENDHLD 012 #define RETURN 013 /* * Matrix defines new state given current state and state of CD,CTS, and SR. */ char action[11][6]{ /* 0,0,0 0,0,1 0,1,0 0,1,1 1,0,0 1,0,1 (CD,CTS,SR) */ INTRPT2,RETURN ,ERROR ,ERROR ,REC ,INTRPT1, /*QUIESNT*/ INTRPT1,QUIESNT,ERROR ,ERROR ,RETURN ,INTRPT1, /*REC*/ RETURN ,QUIESNT,ERROR ,ERROR ,REC ,RETURN , /*INTPRT1*/ ERROR ,ERROR ,SENDHLD,RETURN ,ERROR ,ERROR , /*SEND*/ ERROR ,ERROR ,ERROR ,ERROR ,ERROR ,ERROR , /*ERROR*/ INTRPT1,QUIESNT,ERROR ,ERROR ,RETURN ,INTRPT1, /*RECHLD*/ INTRPT2,RETURN ,INTRPT2,SEND ,REC ,INTRPT1, /*SENDREQ*/ INTRPT2,QUIESNT,INTRPT2,RETURN ,REC ,INTRPT1, /*SENDSTP*/ RETURN ,QUIESNT,ERROR ,ERROR ,REC ,INTRPT1, /*INACT*/ RETURN ,QUIESNT,RETURN ,RETURN ,REC ,INTRPT1, /*INTRPT2*/ ERROR ,ERROR ,RETURN ,RETURN ,ERROR ,ERROR , /*SENDHLD*/ }; /* * Routine to open a half-duplex line. Initialize and wait * for carrier to come on. Establish a process * group for the distribution of quits and interrupts * from the terminal. */ hdopen(dev, atp) struct tty *atp; { register struct tty *tp; register struct proc *pp; tp = atp; tp->t_state =| WOPEN; if ((tp->t_state&ISOPEN) == 0) { tp->t_linest = INACT; tp->t_lword = QDELIM; tp->t_erase = CERASE; tp->t_kill = CKILL; tp->t_speeds = HSPEED | (HSPEED<<8); tp->t_flags = HDUP|EVENP; (*ctlsw[tp->t_dtype].d_param)(dev, tp); } else if (tp->t_state&XCLUDE && u.u_uid!=0) { u.u_error = EBUSY; return; } hdmopen(dev, tp); pp = u.u_procp; if(pp->p_pgrp == 0) { if(tp->t_pgrp) pp->p_pgrp = tp->t_pgrp; else { pp->p_pgrp = pp->p_pid; tp->t_pgrp = pp->p_pid; } u.u_ttyp = tp; u.u_ttyd = dev; } tp->t_state =& ~WOPEN; tp->t_state =| ISOPEN; } /* * Modem open for half-duplex lines. Set up modem to answer phone. * Test state of CD,CTS, and SR and set protocol state accordingly. * Sleep until CD or SR goes high. */ hdmopen(dev, atp) struct tty *atp; { register struct tty *tp; register dtype; tp = atp; dtype = tp->t_dtype; if(tp->t_linest == INACT) (*ctlsw[dtype].d_mctl)(dev, TURNON); spl5(); hdmt(tp,(*ctlsw[dtype].d_mctl)(dev,FSTATUS)); while((tp->t_state&CARR_ON)==0) sleep(&tp->t_rawq, TTIPRI); spl0(); } /* * Close a tty line. */ hdclose(dev, atp) struct tty *atp; { register struct tty *tp; tp = atp; if(tp->t_state&ISOPEN){ if (tp->t_flags&HUPCL) (*ctlsw[tp->t_dtype].d_mctl)(dev, HUP); tp->t_state =& (CARR_ON|SSTART); tp->t_pgrp = 0; wflushtty(tp); } } /* * Handles interrupts caused by transitions of CD,CTS, and SR. The * current protocol state and the new state of CD,CTS and SR determine * the new protocol state and thus the new state of RQS and ST. */ hdmt(atp,status) { register struct tty *tp; int act; int intbits; int modstat; extern timer(); extern sendstp(); extern sendhld(); tp = atp; intbits = status; modstat = 0; /* * Determine new protocol state. */ if(intbits > 5) act = ERROR; else act = action[tp->t_linest][intbits]; /* * Set new protocol state. */ switch(act){ case QUIESNT : modstat = TURNON; if(tp->t_linest == INACT) { tp->t_state =| CARR_ON; wakeup(&tp->t_rawq); } if(tp->t_linest == INTRPT1) if((tp->t_lword&QDELIM) == 0 && (tp->t_flags&RAW) == 0) ttyinput('\n',tp); if(tp->t_linest == INTRPT2){ tp->t_lword =| WRTON; tp->t_state =& ~XMTSTOP; ttstart(tp); modstat = 0; } tp->t_linest = QUIESNT; if(tp->t_lword&SOLICIT){ solicit(tp); modstat = 0; } if(tp->t_lword&SNDRFLG){ hdmset(tp,SENDREQ); modstat = 0; } break; case REC : tp->t_lword =| SOLICIT; modstat = TURNON|ST; tp->t_lword =& ~CURSET; if(tp->t_linest == INACT) { tp->t_state =| CARR_ON; wakeup(&tp->t_rawq); } tp->t_linest = REC; break; case INTRPT1 : tp->t_linest = INTRPT1 ; modstat = TURNON; if(tp->t_lword&LOCAL) break; if(tp->t_lword&TIMER2){ tp->t_lword =| EXTND; } else{ tp->t_lword =| TIMER2; timeout(timer,tp,DISCON); } break; case SEND : tp->t_linest = SEND; ttstart(tp); break; case SENDHLD : tp->t_state =| XMTSTOP; timeout(sendhld,tp,DLAY1); modstat = 0; tp->t_linest = SENDHLD; tp->t_lword =& ~(SNDRFLG|SOLICIT|WRTON); break; case INTRPT2 : tp->t_linest = INTRPT2 ; modstat = TURNON; if(tp->t_lword&LOCAL) break; if(tp->t_lword&TIMER2){ tp->t_lword =| EXTND; } else{ tp->t_lword =| TIMER2; timeout(timer,tp,DISCON); } break; case ERROR : tp->t_linest = ERROR; /*printf("er %o %o %o\n",tp->t_linest,intbits,modstat)*/ hdmset(tp,INACT); } return(modstat); } /* * Set state of modem interface. */ hdmset(atp,state) { register struct tty *tp ; register int st ; int sps,modstat; sps = PS->integ; spl5(); tp = atp; st = state; switch(st){ case REC : tp->t_linest = REC; modstat = TURNON|ST; break; case RECHLD : modstat = TURNON; tp->t_linest = RECHLD; break;  case SENDREQ : tp->t_lword =& ~SNDRFLG; modstat = TURNON|RQS; tp->t_linest = SENDREQ; break; case SENDSTP : tp->t_linest = SENDSTP; modstat = TURNON; break; case INACT : signal(tp->t_pgrp,SIGHUP); flushtty(tp); modstat = HUP; tp->t_linest = INACT; tp->t_state =& ~CARR_ON; break; } (*ctlsw[tp->t_dtype].d_mctl)(tp->t_dev,modstat); PS->integ = sps; } /* * Position cursur to a new line; get characters from user and call hdoutput. */ hdwrite(atp) struct tty *atp; { register struct tty *tp; register int c; tp = atp; if(tp->t_lword&SOLICIT) solicit(tp); if(tp->t_linest != SENDHLD) tp->t_lword =| WRTON; if ((tp->t_state&CARR_ON)==0) return; while ((c=cpass())>=0) { spl5(); while (tp->t_outq.c_cc > TTHIWAT) { ttstart(tp); tp->t_state =| ASLEEP; sleep(&tp->t_outq, TTOPRI); } spl0(); hdoutput(c, tp); } ttstart(tp); tp->t_lword =& ~CURSET; } /* * Call ttyoutput; provide delays for TTY Model 40. */ hdoutput(ac, tp) struct tty *tp; { register int c; register struct tty *rtp; register char *colp; register int dlay; rtp = tp; colp = &rtp->t_col; c = ac&0177; dlay = 0; ttyoutput(c,rtp); if(rtp->t_lword&ESCHA){ switch(c) { case '2': dlay = 10; break; case 'J': dlay = 14; break; case 'R': dlay = 7; *colp = 0; break; case '\010': (*colp)--; break; case 'C': (*colp)++; break; case '@': *colp =| 07; (*colp)++; break; case 'L': case 'M': dlay = 20; break; case 'G': case 'H': *colp = 0; break; } rtp->t_lword =& ~ESCHA; } if(c == '\033') rtp->t_lword =| ESCHA; if(dlay) putc(dlay|0200,&rtp->t_outq); } /* * Position cursur to a new line if no characters are availble. Move * characters from rawq to canq to user to stasfy read. Account for QESC * as result of RECHLD state. */ hdread(atp) struct tty *atp; { struct tty *tp; register int c,c1; int n; tp = atp; spl5(); if(tp->t_delct == 0 && tp->t_rawq.c_cc == 0 && tp->t_canq.c_cc == 0) if((tp->t_lword&CURSET) == 0){ if(tp->t_linest == QUIESNT) solicit(tp); else tp->t_lword =| SOLICIT; } spl0(); while(tp->t_canq.c_cc || hdcanon(tp)){ c1 = -1; n = 0; if((c = getc(&tp->t_canq)) == QESC){ if((c1 = getc(&tp->t_canq)) == QESC) n = passc(c1); }else{ n = passc(c); } if(n<0 || (tp->t_canq.c_cc == 0 && c1 != QBRK )) return; } } /* * Put characters on rawq. Wakeup on additional message ending characters. * Set queue delimiter (QDELIM) flag. Set RECHLD state if rawq gets full. */ hdrcvd(ac,atp) struct tty *atp; { register int t_flags,c; register struct tty *tp; tp = atp; c = ac; t_flags = tp->t_flags; if((c&0177)=='\r') c = (c&0177600)|'\n'; ttyinput(c,tp); if((c =& 0177) == QESC) ttyinput(QESC,tp); if(tp->t_state&XMTSTOP){ tp->t_state =& ~XMTSTOP; tp->t_lword =| WRTON; ttstart; } if(c==035 || c==024){ wakeup(&tp->t_rawq); if((t_flags&RAW)==0 && putc(0377,&tp->t_rawq)==0) tp->t_delct++; } if((t_flags&RAW) || (c=='\n' || c==CEOT || c==035 || c==024)) tp->t_lword =| QDELIM; else tp->t_lword =& ~QDELIM; if(tp->t_rawq.c_cc >= M40STP && tp->t_linest == REC){ hdmset(tp,RECHLD); putc(QESC,&tp->t_rawq); putc(QBRK,&tp->t_rawq); if(putc(0377,&tp->t_rawq) == 0) tp->t_delct++; wakeup(&tp->t_rawq); } } /* * Sets the SENDREQ state when there are characters to pass to the calling * routine. Calls timeout with sendstp when the output queue count is zero. * Returns a character when in the SEND state and characters are available. */ hdxmtd(atp) struct tty *atp; { register struct tty *tp; register c; extern sendstp(); tp = atp; c = 0; if(tp->t_state&XMTSTOP) return(0); if(tp->t_outq.c_cc) if(tp->t_linest == SEND){ c = getc(&tp->t_outq); if(c<=0177) c =| CPRES|(partab[c]&0200); else c =| CTOUT; } else if(tp->t_linest == QUIESNT) hdmset(tp,SENDREQ); else tp->t_lword =| SNDRFLG; else if(tp->t_linest == SEND) tp->t_lword =& ~WRTON; if((tp->t_lword&TIMER1) == 0){ tp->t_lword =| TIMER1; timeout(sendstp,tp,DLAY); } if(tp->t_outq.c_cc <= TTLOWAT && tp->t_state&ASLEEP){ tp->t_state =& ~ASLEEP; wakeup(&tp->t_outq); } return(c); } /* * Common code for tty line disciplines */ hdstty(dev, atp, cmd) struct tty *atp; { register struct tty *tp; register int *v; int word1; tp = atp; v = u.u_arg[1]; switch(cmd) { case UNSET: hdclose(dev, tp); break; case SET: hdopen(dev, tp); break; case CHNGD: case STTY: case STTYNF: case GTTY: /* * Prevent opens on channel. */ case XCLD: case FEK: case SEK: ttstty(dev,atp,cmd); break; default: u.u_error = EBIOCTL; } } /* * Call canon. Allow input when queue reaches low point. */ hdcanon(atp) struct tty *atp; { register struct tty *tp; int n; tp = atp; n = canon(tp); spl5(); if(tp->t_linest == RECHLD && tp->t_rawq.c_cc < M40GO) hdmset(tp,REC); spl0(); if(tp->t_canq.c_cc) return(n); else return(0); } /* * Put bell, backspace, and newline on outq. */ solicit(atp) struct tty *atp; { register struct tty *tp; tp = atp; tp->t_lword =| CURSET; tp->t_lword =& ~SOLICIT; tp->t_lword =| WRTON; ttyoutput('\007',tp); ttyoutput('\010',tp); ttyoutput('\n',tp); ttstart(tp); } /* *Set SENDSTP after timeout. */ sendstp(atp) { register struct tty *tp; tp=atp; if((tp->t_state&(TIMEOUT|BUSY)) == 0 && (tp->t_lword&WRTON) == 0 && (tp->t_linest == SEND)) if(tp->t_lword&SOLICIT) solicit(tp); else hdmset(tp,SENDSTP); tp->t_lword =& ~TIMER1; } /* * Unconditionally set SENDSTP state. */ sendhld(atp) { register struct tty *tp; tp = atp; if(tp->t_linest == SENDHLD) hdmset(tp,SENDSTP); } /* * Set INACT if no carrier for timeout period. */ timer(atp) { register struct tty *tp; tp=atp; if((tp->t_linest != INTRPT1) && (tp->t_linest != INTRPT2)){ tp->t_lword =& ~(EXTND|TIMER2); return; } if(tp->t_lword&EXTND){ timeout(timer,tp,DISCON); tp->t_lword =& ~EXTND; } else{ hdmset(tp,INACT); tp->t_lword =& ~TIMER2; } } ~TIMER1; } /* * Unconditionally set SENDSTP state. */ sendhld(atp) { register struct tty *tp; tp = atp; if(tp->t_linest == SENDHLD) hdmset(tp,SENDSTP); } /* * Set INACT if no carrier for timeout period. */ timer(atp) { register struct tty *tp; tp=atp; if((tp->t_linest != INTRPT1) && (tp->t_linest != INTRPT2)){ tp->t_lword =& ~(EXTND|TIMER2); return; } if(tp->t_lword&EXTND){ timeout(timer,tp,DISCON); tp->t_lword =& ~EXTND; } else{ hdmset(tp,INACT); tp->t_lword =& # /* cm.c driver for minitape controller, character device */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" /* commands for tape control system */ #define DINIT 0100 /* drive initialization */ #define UNLD 0105 /* unload cartridge -- wait for completion */ #define SNB 0111 /* set byte cnt n - all drives */ /* sent as lob and hob each with even parity */ #define SMF 0114 /* set record cnt m for spacing - all drives */ /* sent as lob and hob each with even parity */ #define LDTS 0121 /* load drive and track select */ #define WRT 0124 /* write n bytes */ #define WTM 0130 /* write a tape mark */ #define WGP 0135 /* write an extended gap */ #define RD 0141 /* read n bytes or less */ #define RSW 0144 /* read status word */ #define SPFM 0150 /* space forward m records */ #define SPRM 0155 /* space reverse m records */ #define STMF 0160 /* space to tape mark forward */ #define STMR 0165 /* space to tape mark reverse */ #define RWD 0171 /* rewind to LPT */ #define RCRC 0174 /* read crc character */ #define CLAF 0200 /* clear all flags (status word) */ /* status word, first byte bits 0-6, 7 prog uses */ #define RDER 1 /* read error exists after 10 retries */ /* or total failure in writing */ #define EW 2 /* early warning */ #define TMD 4 /* tape mark detected */ #define DPTM 010 /* n is smaller than record read, */ /* or bytes transferred in write not equal to n */ #define WNWEN 020 /* write with protect on - attempted */ #define SPTD 040 /* space operation terminated at EOT or BOT */ #define NONL 0100 /* selected drive off line */ #define TERR 0200 /* timeout on request to controller */ /* status word, second byte bits 0-6, 7 prog uses */ #define TOR 0400 /* tape off reel */ #define EOT 01000 /* end of tape */ #define BOT 02000 /* begining of tape */ #define LPT 04000 /* load point */ #define NRDY 010000 /* execute while not ready */ #define ILCMD 020000 /* illegal cmd or wrong parity on cmd or its arg */ #define RWDG 040000 /* selected drive rewinding when set */ #define SERR 0100000 /*can't read or can't clear status */ #define INTAE 0100 /* data interrupt enable (A interrupt) */ #define INTBE 040 /* command interrupt enable (B interrupt) */ #define CSR0 1 /* control bit 0 to device, set = cmd */ #define CSRN 0 /* control bit 0 to device, clr = data */ #define REQA 0200 /* request A */ #define REQB 0100000 /* request B */ #define RAW 05 #define ILLEGAL 03 /* track adr overflow */ #define NUNIT 4 #define CMADDR 0167750 /* address of dr11-c */ #define FWRITE 02 struct { int cstat; /* dr11-c offsets */ int cout; int cin; }; int c_active; /* controller busy flag*/ char c_test[NUNIT]; /* < 04 = single track only */ char c_open[NUNIT]; char c_ldts[NUNIT] {020,040,0100,0200}; /* bits 4-7 = unit. 0,1 = track */ char c_flgb[NUNIT]; int c_stau[NUNIT]; /* drive status words */ int c_mblkno[NUNIT]; int c_drv; char c_flgc; char c_sleep; /* minors for drives 1,2,3,4 respectively */ /* track 1 single file 0,8,16,24 */ /* track 2 single file 1,9,17,25 */ /* track 3 single file 2,10,18,26 */ /* track 4 single file 3,11,19,27 */ /* multi-track single file 4,12,20,28 */ /* multi-track multi-file 5,13,21,29 */ /* NOTE: The maximum permissible tranfer rate of data or */ /* arguments to or from the cartridge controller is 100kc */ cmopen(dev, flag) { register drv,drv1; drv1 = drv = dev.d_minor; drv = (drv >> 3) & 03; /* physical drive */ if (c_open[drv]) u.u_error = ENXIO; /* already in use */ else { c_open[drv]++; /* mark unit busy */ c_mblkno[drv] = 0; /* clr seek # */ c_stau[drv] = 0; /* clr status */ c_flgb[drv] = 1; /* initialize drive */ c_test[drv] = drv1 =& 07; if (drv1 != RAW) /* if not RAW new track */ { c_ldts[drv] =& 0360; c_ldts[drv] =| (drv1 & 03); } } } cmclose(dev, flag) { register int drv; drv = (dev.d_minor >> 3) &03; c_flgb[drv] = 3; /* read close */ if (flag & FWRITE) c_flgb[drv]--; /* write close */ cmstart(drv); c_open[drv] = 0; /* free drive */ } cmread(dev) { register int drv; drv = (dev.d_minor >> 3) &03; /* physical drive # */ c_open[drv] = RD; cmstart(drv); } cmwrite(dev) { register int drv; drv = (dev.d_minor >> 3) &03; /* physical drive # */ c_open[drv] = WRT; cmstart(drv); } cmstart(driv) { extern char partab[]; register int drv,b,c; drv = driv; /* physical drive # */ if(c_active) /* sleep if in use */ { spl5(); c_sleep++; while(c_active) sleep(&c_sleep,-1); c_sleep--; spl0(); } c_drv = drv; c_active++;  /* mark busy */ cwtrd: if(cminit() < 0) goto cerror; switch(c_flgb[drv]) { /* initial & closing routines */ case 2: if((b = cmslp(WTM)) < 0) goto cerror; /* write 1st tape mark */ if(b & EOT) { if((c = cmrwd()) < 0) goto cerror; } if(cmslp(WTM) < 0) goto cerror; /* write 2nd tape mark */ if(b & EOT) goto cunlod; /* only 2nd tm on track */ if(cmslp(SPRM) < 0) goto cerror; /* backspace 1 record */ case 3: if(c_test[drv] == RAW) goto cdone; cunlod: if(cmslp(UNLD) < 0) goto cerror; /* unload */ goto cdone; case 1: if (c_test[drv] == RAW) { if((c = cmstatus()) < 0) goto cerror; if (c & LPT) { c_ldts[drv] =& 0360; /* track 0 */ if(cminit() < 0) goto cerror; /* chg track */ goto cinit; } if((c & BOT) == 0) break; } cinit: if(cmslp(DINIT) < 0) goto cerror; /* initialize drive */ if(cmslp(SMF) < 0) goto cerror; /* spacing arg next */ CMADDR->cstat = CSRN; CMADDR->cout = 0201; /* set space for 1 record */ cmdelay(); CMADDR->cout = 0; /* 2nd byte */ if(cmwait(INTBE) < 0) goto cerror; } /* read & write operations */ c_flgb[drv] = 0; if(((c = c_mblkno[drv]) != (b = lshift(u.u_offset,-9))) && ((u.u_offset[1] & 0777) == 0)) { if(cmseek(c,b) < 0) goto cerror; c_mblkno[drv] = b; } if(cmslp(SNB) < 0) goto cerror; /* byte cnt args next */ c = b = u.u_count; /* positive byte cnt */ /* cnt <10 or >2048 = error */ b =& 0177; b =| (partab[b] & 0200); /* add even parity */ c = (c >> 7) & 0177; c =| (partab[c] & 0200);  /* add even parity */ CMADDR->cstat = CSRN; CMADDR->cout = b; /* send cnt low order byte */ cmdelay(); CMADDR->cout = c; /* send cnt high order byte */ if(cmwait(INTBE) < 0) goto cerror; if (c_open[drv] == WRT) /* write */ { if(cmslp(WRT) < 0) goto cerror; /* write command */ CMADDR->cstat = CSRN; while ((c = cpass()) != -1) CMADDR->cout = c; /* char to controller */ if((c = cmslp(0)) < 0) goto cerror; /* sleep */ if(c & EOT) if((c = cmrwd()) < 0) goto cerror; goto ccount; } if((c = cmslp(RD)) < 0) goto cerror; /* sleep till readable */ if(c & TMD) goto ccount; if(c & EOT) { if(c = cmrwd() < 0) goto cerror; goto cwtrd; /* read again */ } CMADDR->cstat = CSRN; while((CMADDR->cstat & REQB) == 0) /* record < than req */ if ((passc(CMADDR->cin)) != 0) break; if(cmwait(INTBE) >= 0) /* wait for B request */ { ccount: c_mblkno[drv]++; goto cdone; } cerror: u.u_error = EIO; /* report error */ cdone: c_active = 0; /* free controller */ if(c_sleep > 0) wakeup(&c_sleep); } cmintr() { CMADDR->cstat = 0; /* kill interrupts */ wakeup(&c_active); } cminit() { if(cmslp(LDTS) < 0) return(-1); /* select drive */ CMADDR->cstat = CSRN; CMADDR->cout = c_ldts[c_drv]; /* drive & track argument */ if(cmwait(INTBE) < 0) return(-1); } cmseek(cur,sek) { register int x,y,z; x = cur; /* current record block # */ y = sek; /* record block # sought */ if(x < y) { while(x != y) { if((z = cmslp(SPFM)) < 0) break; if(z & SPTD) { if(cmrwd() < 0) break; if(cminit() != 0) break; } x++; } goto cog; } while(x != y) { if((z = cmslp(SPRM)) < 0) break; if(z & SPTD) { if(c_test[c_drv] > ILLEGAL && (c_ldts[c_drv] & 3) != 0) { c_ldts[c_drv]--; if(cminit() != 0) break; while((z & EOT) == 0) if((z = cmslp(STMF)) < 0)goto cog; } else break; } x--; } cog: if(x != y) return(-1); /* failed */ } cmdelay() { } cmrwd() { if(c_test[c_drv] > ILLEGAL && (c_ldts[c_drv] & 3) < ILLEGAL) { c_ldts[c_drv]++; /* inc track */ return(cmslp(RWD)); /* rewind: 0=ok,negative=trouble */ } return(-1); /* Illegal, no rewind performed */ } cmslp(cmmd) { register int b,c; if((c = cmmd)) { CMADDR->cstat = CSR0; CMADDR->cout = c; /* send command */ } b = INTAE; if((c > WRT && c != RSW) || c < SNB) { if(c != RD) b = INTBE; spl5(); /* insure sleep */ CMADDR->cstat =| b; /* enable interrupt */ while(CMADDR->cstat & b) sleep(&c_active,-1); spl0(); } return(cmwait(b)); /* 0=ok,negative=trouble */ } cmwait(boa) { register int b,c,d; b = REQB; if(boa == INTBE) d = REQA; else { d = b; b = REQA; } for (c = 0;c < 200;c++) { if (CMADDR->cstat & b) /* look for expected request */ { if (CMADDR->cstat & d) /* both requests, get status */ { if(c_flgc) return(-1); return(cmstatus()); } return(0); } } c_stau[c_drv] =| TERR; /* request overdue = error */ return(-1); /* trouble */ } cmstatus() { register int c,b; c_flgc++; /* cmstatus is caller */ if(cmslp(RSW) < 0) goto werror; /* read status */ CMADDR->cstat = CSRN; c = CMADDR->cin & 0177; /* 1st status byte */ cmdelay(); b = CMADDR->cin; /* 2nd status byte */ b = (b << 8) & 077400; c_stau[c_drv] = c =| b; if(cmwait(INTBE) < 0) goto werror; CMADDR->cstat = CSR0; CMADDR->cout = CLAF; /* clear flags */ if(cmwait(INTBE) < 0) { werror: c = -1; c_stau[c_drv] =| SERR; /* status read or clr ng */ } if (c & (RDER|DPTM|WNWEN|NONL|TOR|NRDY|ILCMD)) c = -1; c_flgc = 0; return(c); } cmslp(RSW) < 0) goto werror; /* read status */ CMADDR->cstat = CSRN; c = CMADDR->cin & 0177; /* 1st status byte */ cmdelay(); b = CMADDR->cin; /* 2nd status byte */ b = (b << 8) & 077400; c_stau[c_drv] = c =| b; if(cmwait(INTBE) < 0) goto werror; CMADDR->cstat = CSR0; CMADDR->cout = CLAF; /* clear flags */ if(cmwait(INTBE) < 0) { werror: c = -1; c_stau[c_drv] =| SERR; /* status read or clr ng */ } if (c & (RDER|DPTM|WNWEN|NONL|TOR|NRDY|ILCMD)) c = -1; c_flgc = 0; r#include "../head/param.h" #include "../head/systm.h" /* * Allocate 'size' units from the given * map. Return the base of the allocated * space. * In a map, the addresses are increasing and the * list is terminated by a 0 size. * The core map unit is 64 bytes; the swap map unit * is 512 bytes. * Algorithm is first-fit. */ malloc(mp, size) struct map *mp; { register int a; register struct map *bp; for (bp=mp; bp->m_size; bp++) { if (bp->m_size >= size) { a = bp->m_addr; bp->m_addr =+ size; if ((bp->m_size =- size) == 0) do { bp++; (bp-1)->m_addr = bp->m_addr; } while ((bp-1)->m_size = bp->m_size); return(a); } } return(0); } /* * Free the previously allocated space aa * of size units into the specified map. * Sort aa into map and combine on * one or both ends if possible. */ mfree(mp, size, aa) struct map *mp; char *aa; { register struct map *bp; register int t; register char *a; a = aa; if ((bp = mp)==coremap && runin) { runin = 0; wakeup(&runin); /* Wake scheduler when freeing core */ } for (; bp->m_addr<=a && bp->m_size!=0; bp++); if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) { (bp-1)->m_size =+ size; if (a+size == bp->m_addr) { (bp-1)->m_size =+ bp->m_size; while (bp->m_size) { bp++; (bp-1)->m_addr = bp->m_addr; (bp-1)->m_size = bp->m_size; } } } else { if (a+size == bp->m_addr && bp->m_size) { bp->m_addr =- size; bp->m_size =+ size; } else if (size) do { t = bp->m_addr; bp->m_addr = a; a = t; t = bp->m_size; bp->m_size = size; bp++; } while (size = t); } } e!=0; bp++); if (bp>mp && (bp-1)->m_addr+(bp-1)->m_size == a) { (bp-1)->m_size =+ size; if (a+size == bp->m_addr) { (bp-1)->m_size =+ bp->m_size; while (bp->m_size) { bp++; (bp-1)->m_addr = bp->m_addr; (bp-1)->m_size = bp->m_size; } } } else { if (a+size == bp->m_addr && bp->m_size) { bp->m_addr =- size; bp->m_size =+ size; } else if (size) do { t = bp->m_addr; bp->m_addr = a; a =# /* */ /* * Memory special file * minor device 0 is physical memory * minor device 1 is kernel memory * minor device 2 is EOF/RATHOLE */ #include "../head/param.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/conf.h" #include "../head/seg.h" mmread(dev) { register c, bn, on; int a, d; if(dev.d_minor == 2) return; do { bn = lshift(u.u_offset, -6); on = u.u_offset[1] & 077; a = UISA->r[0]; d = UISD->r[0]; spl7(); UISA->r[0] = bn; UISD->r[0] = 077406; if(dev.d_minor == 1) UISA->r[0] = (ka6-6)->r[(bn>>7)&07] + (bn & 0177); if ((c = fuibyte(on)) < 0) u.u_error = ENXIO; UISA->r[0] = a; UISD->r[0] = d; spl0(); } while(u.u_error==0 && passc(c)>=0); } mmwrite(dev) { register c, bn, on; int a, d; if(dev.d_minor == 2) { c = u.u_count; u.u_count = 0; u.u_base =+ c; dpadd(u.u_offset, c); return; } for(;;) { bn = lshift(u.u_offset, -6); on = u.u_offset[1] & 077; if ((c=cpass())<0 || u.u_error!=0) break; a = UISA->r[0]; d = UISD->r[0]; spl7(); UISA->r[0] = bn; UISD->r[0] = 077406; if(dev.d_minor == 1) UISA->r[0] = (ka6-6)->r[(bn>>7)&07] + (bn & 0177); if (suibyte(on, c) < 0) u.u_error = ENXIO; UISA->r[0] = a; UISD->r[0] = d; spl0(); } } n, on; int a, d; if(dev.d_minor == 2) { c = u.u_count; u.u_count = 0; u.u_base =+ c; dpadd(u.u_offset, c); return; } for(;;) { bn = lshift(u.u_offset, -6); on = u.u_offset[1] & 077; if ((c=cpass())<0 || u.u_error!=0) break; a = UISA->r[0]; d/* */ char partab[] { 0001,0201,0201,0001,0201,0001,0001,0201, 0202,0004,0003,0205,0005,0206,0201,0001, 0201,0001,0001,0201,0001,0201,0201,0001, 0001,0201,0201,0001,0201,0001,0001,0201, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,0200,0200,0000, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,0200,0200,0000, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0201 }; 0201, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,0200,0200,0000, 0200,0000,0000,0200,0000,0200,0200,0000, 0000,0200,0200,0000,0200,0000,0000,0200, 0000,0200,0200,0000,0200,0000,0000,0200, 0200,0000,0000,0200,0000,# /* */ /* * PC-11 Paper tape reader/punch driver */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #define PCADDR 0177550 #define FWRITE 02 /* open for writing */ #define CLOSED 0 #define WAITING 1 #define READING 2 #define EOF 3 #define RDRENB 01 #define IENABLE 0100 #define DONE 0200 #define BUSY 04000 #define ERROR 0100000 #define PCIPRI 30 #define PCOPRI 40 #define PCOLWAT 50 #define PCOHWAT 100 #define PCIHWAT 250 struct { int pcrcsr; int pcrbuf; int pcpcsr; int pcpbuf; }; struct clist { int cc; int cf; int cl; }; struct pc11 { int pcstate; struct clist pcin; struct clist pcout; } pc11; pcopen(dev, flag) { extern lbolt; if ((flag&FWRITE)==0) { if (pc11.pcstate!=CLOSED) { u.u_error = ENXIO; return; } pc11.pcstate = WAITING; while(pc11.pcstate==WAITING) { PCADDR->pcrcsr = IENABLE|RDRENB; sleep(&lbolt, PCIPRI); } } else { PCADDR->pcpcsr =| IENABLE; pcleader(); } } pcclose(dev, flag) { if ((flag&FWRITE)==0) { spl4(); while (getc(&pc11.pcin) >= 0); PCADDR->pcrcsr = 0; pc11.pcstate = CLOSED; spl0(); } else pcleader(); } pcread() { register int c; spl4(); do { while ((c = getc(&pc11.pcin)) < 0) { if (pc11.pcstate==EOF) goto out; if ((PCADDR->pcrcsr&(ERROR|BUSY|DONE))==0) PCADDR->pcrcsr =| IENABLE|RDRENB; sleep(&pc11.pcin, PCIPRI); } } while (passc(c)>=0); out: spl0(); } pcwrite() { register int c; while ((c=cpass())>=0) pcoutput(c); } pcstart() { register int c; if (PCADDR->pcpcsr&DONE && (c = getc(&pc11.pcout)) >= 0) PCADDR->pcpbuf = c; } pcrint() { if (pc11.pcstate==WAITING) { if (PCADDR->pcrcsr&ERROR) return; pc11.pcstate = READING; } if (pc11.pcstate==READING) { if (PCADDR->pcrcsr&ERROR) pc11.pcstate = EOF; else { putc(PCADDR->pcrbuf, &pc11.pcin); if (pc11.pcin.cc < PCIHWAT) PCADDR->pcrcsr =| IENABLE|RDRENB; } wakeup(&pc11.pcin); } } pcpint() { pcstart(); if (pc11.pcout.cc <= PCOLWAT) wakeup(&pc11.pcout); } pcoutput(c) { if (PCADDR->pcpcsr&ERROR) { u.u_error = EIO; return; } if (pc11.pcout.cc >= PCOHWAT) sleep(&pc11.pcout, PCOPRI); putc(c, &pc11.pcout); spl4(); pcstart(); spl0(); } pcleader() { register int i; i = 100; do pcoutput(0); while (--i); } .pcstate = EOF; else { putc(PCADDR->pcrbuf, &pc11.pcin); if (pc11.pcin.cc < PCIHWAT) PCADDR->pcrcsr =| IENABLE|RDRENB; } wakeup(&pc11.pcin); } } pcpint() { pcstart(); if (pc11.pcout.cc <= PCOLWAT) wakeup(&pc11.pcout); # #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/file.h" #include "../head/filex.h" #include "../head/reg.h" /* * Max allowable buffering per pipe. * This is also the max size of the * file created to implement the pipe. * If this size is bigger than 4096, * pipes will be implemented in LARG * files, which is probably not good. */ #define PIPSIZ 4096 /* * The sys-pipe entry. * Allocate an inode on the root device. * Allocate 2 file structures. * Put it all together with flags. */ pipe() { register *ip, *rf, *wf; int r; ip = ialloc(rootdev); if(ip == NULL) return; rf = falloc(); if(rf == NULL) { iput(ip); return; } r = u.u_ar0[R0]; wf = falloc(); if(wf == NULL) { rf->f_count = 0; u.u_ofile[r] = NULL; iput(ip); return; } u.u_ar0[R1] = u.u_ar0[R0]; u.u_ar0[R0] = r; wf->f_flag = FWRITE|FPIPE; wf->f_inode = ip; rf->f_flag = FREAD|FPIPE; rf->f_inode = ip; ip->i_count = 2; ip->i_flag = IACC|IUPD; ip->i_mode = IALLOC; } /* * Read call directed to a pipe. */ readp(fp) int *fp; { register *rp, *ip; rp = fp; ip = rp->f_inode; loop: /* * Very conservative locking. */ plock(ip); /* * If nothing in the pipe, wait. */ if (ip->i_size1==0) { /* * If there are not both reader and * writer active, return without * satisfying read. */ prele(ip); if(ip->i_count < 2) return; ip->i_mode =| IREAD; sleep(ip+2, PPIPE); goto loop; } /* * Read and return */ u.u_offset[0] = 0; u.u_offset[1] = rp->f_offset[1]; readi(ip); rp->f_offset[1] = u.u_offset[1]; /* * If reader has caught up with writer, reset * offset and size to 0. */ if (rp->f_offset[1] == ip->i_size1) { rp->f_offset[1] = 0; ip->i_size1 = 0; if (ip->i_mode&IWRITE) { ip->i_mode =& ~IWRITE; wakeup(ip+1); } } prele(ip); } /* * Write call directed to a pipe. */ writep(fp) { register *rp, *ip, c; rp = fp; ip = rp->f_inode; c = u.u_count; loop: /* * If all done, return. */ plock(ip); if(c == 0) { prele(ip); u.u_count = 0; return; } /* * If there are not both read and * write sides of the pipe active, * return error and signal too. */ if(ip->i_count < 2) { prele(ip); u.u_error = EPIPE; psignal(u.u_procp, SIGPIPE); return; } /* * If the pipe is full, * wait for reads to deplete * and truncate it. */ if(ip->i_size1 >= PIPSIZ) { ip->i_mode =| IWRITE; prele(ip); sleep(ip+1, PPIPE); goto loop; } /* * Write what is possible and * loop back. * If writing less than PIPSIZ, it always goes. * One can therefore get a file > PIPSIZ if write * sizes do not divide PIPSIZ. */ u.u_offset[0] = 0; u.u_offset[1] = ip->i_size1; u.u_count = min(c, PIPSIZ); c =- u.u_count; writei(ip); prele(ip); if(ip->i_mode&IREAD) { ip->i_mode =& ~IREAD; wakeup(ip+2); } goto loop; } /* * Lock a pipe. * If its already locked, * set the WANT bit and sleep. */ plock(ip) int *ip; { register *rp; rp = ip; while(rp->i_flag&ILOCK) { rp->i_flag =| IWANT; sleep(rp, PPIPE); } rp->i_flag =| ILOCK; } /* * Unlock a pipe. * If WANT bit is on, * wakeup. * This routine is also used * to unlock inodes in general. */ prele(ip) int *ip; { register *rp; rp = ip; rp->i_flag =& ~ILOCK; if(rp->i_flag&IWANT) { rp->i_flag =& ~IWANT; wakeup(rp); } } akeup(ip+2); } goto loop; } /* * Lock a pipe. * If its already locked, * set the WANT bit and sleep. */ plock(ip) int# /* * RF disk driver */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" struct rfregs { int rfcs; int rfwc; int rfba; int rfda; int rfdae; }; #define NRF 1 #define NRFBLK 1024 #define RFADDR 0177460 struct devtab rftab; struct buf rrfbuf; struct iostat rfstat[NRF]; struct errtab rfetab { etabinit(E_BLK,NRF,RF,rfstat) }; #define GO 01 #define RCOM 02 #define WCOM 04 #define CTLCLR 0400 #define IENABLE 0100 /* * Monitoring device number */ #define DK_N 0 rfopen(dev, flag) { if(dev.d_minor >= NRF) u.u_error = ENXIO; } rfstrategy(abp) struct buf *abp; { register struct buf *bp; bp = abp; if(bp->b_flags&B_PHYS) mapalloc(bp); if (bp->b_blkno >= NRFBLK*(bp->b_dev.d_minor+1)) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = 0; spl5(); if (rftab.d_actf==0) rftab.d_actf = bp; else rftab.d_actl->av_forw = bp; rftab.d_actl = bp; if (rftab.d_active==0) rfstart(); spl0(); } rfstart() { register struct buf *bp; if ((bp = rftab.d_actf) == 0) return; rftab.d_active++; rfetab.e_aunit = &rfstat[(bp->b_blkno.hibyte>>2)&07]; rfetab.e_aunit->io_ops++; blkacty =| (1<rfdae = bp->b_blkno.hibyte; devstart(bp, &RFADDR->rfda, bp->b_blkno<<8, 0); dk_busy =| 1<b_wcount>>5) & 03777; } rfintr() { register struct buf *bp; struct rfregs rfregs[0]; if (rftab.d_active == 0) return; blkacty =& ~(1<rfcs < 0) { /* error bit */ /* deverror(bp, RFADDR->rfcs, RFADDR->rfdae); /**/ fmtblk(&rfetab,RFADDR,sizeof(rfregs[0])/2,bp); RFADDR->rfcs = CTLCLR; if (rftab.d_errcnt < 10) { if(rftab.d_errcnt++ == 0) logerr(&rfetab,E_FIRST); rfstart(); return; } bp->b_flags =| B_ERROR; } if(rfetab.e_emsg != NULL) logerr(&rfetab,E_RETRY); rftab.d_errcnt = 0; rftab.d_actf = bp->av_forw; bp->b_resid = RFADDR->rfwc; iodone(bp); rfstart(); } rfread(dev) { physio(rfstrategy, &rrfbuf, dev, B_READ, NRFBLK*(dev.d_minor+1)); } rfwrite(dev) { physio(rfstrategy, &rrfbuf, dev, B_WRITE, NRFBLK*(dev.d_minor+1)); } ])/2,bp); RFADDR->rfcs = CTLCLR; if (rftab.d_errcnt < 10) { if(rftab.d_errcnt++ == 0) logerr(&rfetab,E_FIRST); rfstart(); return; } bp-# /* */ #include "../head/param.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/seg.h" /* * startup routine for RH controllers. */ #define IENABLE 0100 #define RHWCOM 060 #define RHRCOM 070 #define GO 01 rhstart(bp, devloc, devblk, abae) struct buf *bp; int *devloc, *abae; { register int *dp; register struct buf *rbp; register int com; dp = devloc; rbp = bp; if(cputype == 70) *abae = rbp->b_xmem; *dp = devblk; /* block address */ *--dp = rbp->b_addr; /* buffer address */ *--dp = rbp->b_wcount; /* word count */ com = IENABLE | GO | ((rbp->b_xmem & 03) << 8); if (rbp->b_flags&B_READ) /* command + x-mem */ com =| RHRCOM; else com =| RHWCOM; *--dp = com; } /* * 11/70 routine to allocate the * UNIBUS map and initialize for * a unibus device. * The code here and in * rhstart assumes that an rh on an 11/70 * is an rh70 and contains 22 bit addressing. */ int mapwant; mapalloc(abp) struct buf *abp; { register i, j; register struct buf *bp; long dble; int regno; bp = abp; if(cputype != 70 || bp->b_wcount == 0) return; j = (-bp->b_wcount-1)/4096+1; spl6(); while((regno = malloc(ubmap, j)) == 0) { mapwant++; sleep(ubmap, PSWP); } spl0(); dble.loword = bp->b_addr; dble.hiword = bp->b_xmem; j = 2*(regno+j); for(i = regno*2; ir[i] = dble.loword; UBMAP->r[i+1] = dble.hiword; dble =+ 8192; } bp->b_xmem = regno>>3; bp->b_addr = regno<<13; bp->b_flags =| B_MAP; } mapfree(abp) struct buf *abp; { register struct buf *bp; register regno; bp = abp; bp->b_flags =& ~B_MAP; regno = bp->b_xmem<<3 | ((bp->b_addr>>13)&07); mfree(ubmap, (-bp->b_wcount-1)/4096+1, regno); if(mapwant) { wakeup(ubmap); mapwant = 0; } } /* * For inverted disk areas, negcyl cchecks physical I/O * requests to see if they cross cylinder boundaries and * breaks the request into two parts if needed */ /* * NOTE: THE SWAP AREA MAY NOT BE ON AN INVERTED DISK AREA */ negcyl(strat,bp,dev,flag,nblks,nsect) struct buf *bp; int (*strat)(); { register char *bend,*beg; register char *count; char *savcnt; count = u.u_count; beg = lshift(u.u_offset,-9); bend = beg + ((count>>9)&0177) - ((count&0777)?0:1); if((bend > beg)&&(ldiv(bend,nsect)!=ldiv(beg,nsect))){ savcnt = u.u_count = (nsect - lrem(beg,nsect))*512; physio(strat,bp,dev,flag,nblks); if(u.u_error) return; if(u.u_count){ u.u_count =+ count - savcnt; return(1); } dpadd(u.u_offset,savcnt); u.u_count = count - savcnt; u.u_base =+ savcnt; } return(0); } (); { register char *bend,*beg; register char *count; char *savcnt; count = u.u_count; beg = lshift(u.u_offset,-9); bend = beg + ((count>>9)&0177) - ((count&0777)?0:1); if((bend > beg)&&(ldiv(bend,nsect)!=ldiv(beg,nsect))){ savcnt = u.u_count = (nsect - lrem(beg,nsect))*512; physio(strat,bp,dev,flag,nblks); if(u.u_error) return; if(u.u_/* * Fake rh code for 11/40's */ mapalloc() { } mapfree() { } u.u_offset,savcnt); u.u_count = count - savcnt; u.u_base =+ savcnt; } return(0); } (); { register char *bend,*beg; register char *count; char *savcnt; count = u.u_count; beg = lshift(u.u_offset,-9); bend = beg + ((count>>9)&0177) - ((count&0777)?0:1); if((bend > beg)&&(ldiv(bend,nsect)!=ldiv(beg,nsect))){ savcnt = u.u_count = (nsect - lrem(beg,nsect))*512; physio(strat,bp,dev,flag,nblks); if(u.u_error) return; if(u.u_# /* * RK disk driver */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" #define NRK 4 #define NRKBLK 4872 #define RKADDR 0177400 #define RESET 0 #define GO 01 #define DRESET 014 #define IENABLE 0100 #define DRY 0200 #define ARDY 0100 #define WLO 020000 #define CTLRDY 0200 /* * Monitoring device bit */ #define DK_N 1 struct rkregs { int rkds; int rker; int rkcs; int rkwc; int rkba; int rkda; }; struct devtab rktab; struct buf rrkbuf; struct iostat rkstat[NRK]; struct errtab rketab { etabinit(E_BLK,NRK,RK,rkstat) }; rkopen(dev, flag) { if((dev.d_minor&07) >= NRK) /* even in interleaved, max */ u.u_error = ENXIO; /* unit num must be < NRK */ } rkstrategy(abp) struct buf *abp; { register struct buf *bp; register int d; bp = abp; if(bp->b_flags&B_PHYS) mapalloc(bp); d = bp->b_dev.d_minor-7; if(d <= 0) d = 1; if (bp->b_blkno >= NRKBLK*d) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = 0; spl5(); if (rktab.d_actf==0) rktab.d_actf = bp; else rktab.d_actl->av_forw = bp; rktab.d_actl = bp; if (rktab.d_active==0) rkstart(); spl0(); } rkaddr(bp) struct buf *bp; { register int b, d, m; b = bp->b_blkno; m = bp->b_dev.d_minor - 7; if(m <= 0) d = bp->b_dev.d_minor; else { d = lrem(b, m); b = ldiv(b, m); } rketab.e_aunit = &rkstat[d]; return(d<<13 | (b/12)<<4 | b%12); } rkstart() { register struct buf *bp; register a; if ((bp = rktab.d_actf) == 0) return; rktab.d_active++; a = rkaddr(bp); /* also sets e_aunit */ rketab.e_aunit->io_ops++; blkacty =| (1<rkda, a, 0); dk_busy =| 1<b_wcount>>5) & 03777; } rkintr() { register struct buf *bp; struct rkregs rkregs[0]; if (rktab.d_active == 0) return; blkacty =& ~(1<rkcs < 0) { /* error bit */ /* deverror(bp, RKADDR->rker, RKADDR->rkds); /**/ fmtblk(&rketab,RKADDR,sizeof(rkregs[0])/2,bp); RKADDR->rkcs = RESET|GO; rketab.e_aunit->io_misc++; while((RKADDR->rkcs&CTLRDY) == 0) ; if (rktab.d_errcnt < 10) { if(rktab.d_errcnt++ == 0) logerr(&rketab,E_FIRST); rkstart(); return; } bp->b_flags =| B_ERROR; } if(rketab.e_emsg != NULL) logerr(&rketab,E_RETRY); rktab.d_errcnt = 0; rktab.d_actf = bp->av_forw; bp->b_resid = RKADDR->rkwc; iodone(bp); rkstart(); } rkread(dev) { register nblks; nblks = dev.d_minor - 7; if (nblks <= 0) nblks = 1; physio(rkstrategy, &rrkbuf, dev, B_READ, NRKBLK*nblks); } rkwrite(dev) { register nblks; nblks = dev.d_minor - 7; if (nblks <= 0) nblks = 1; physio(rkstrategy, &rrkbuf, dev, B_WRITE, NRKBLK*nblks); } art(); return; } bp->b_flags =| B_ERROR; } if(rketab.e_emsg != NULL) logerr(&rketab,E_# /* * RP disk driver */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" struct rpregs { int rpds; int rper; int rpcs; int rpwc; int rpba; int rpca; int rpda; }; #define RPADDR 0176710 #define NRP 2 struct { char *nblocks; int cyloff; } rp_sizes[] { 40600L, 0, /* cyl 0 thru 202 */ 40600L, 203, /* cyl 203 thru 405 */ 9200, 0, /* cyl 0 thru 45 */ 9200, 360, /* cyl 360 thru 405 */ 65535L, 0, /* cyl 0 thru 327 */ 65535L, 78, /* cyl 78 thru 405 */ 15600, 0, /* cyl 0 thru 77 */ 15600, 328, /* cyl 328 thru 405 */ }; struct devtab rptab; struct buf rrpbuf; struct iostat rpstat[NRP]; struct errtab rpetab { etabinit(E_BLK,NRP,RP,rpstat) }; #define GO 01 #define RESET 0 #define HSEEK 014 #define IENABLE 0100 #define READY 0200 #define SUFU 01000 #define SUSU 02000 #define SUSI 04000 #define HNF 010000 /* * Use av_back to save track+sector, * b_resid for cylinder. */ #define trksec av_back #define cylin b_resid /* * Monitoring device number */ #define DK_N 2 rpopen(dev, flag) { if (dev.d_minor >= (NRP<<3)) u.u_error = ENXIO; } rpstrategy(abp) struct buf *abp; { register struct buf *bp; register char *p1, *p2; bp = abp; if(bp->b_flags&B_PHYS) mapalloc(bp); p1 = &rp_sizes[bp->b_dev.d_minor&07]; if(bp->b_blkno >= p1->nblocks) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = 0; bp->cylin = p1->cyloff; p1 = bp->b_blkno; p2 = lrem(p1, 10); p1 = ldiv(p1, 10); bp->trksec = (p1%20)<<8 | p2; bp->cylin =+ p1/20; spl5(); if ((p1 = rptab.d_actf)==0) rptab.d_actf = bp; else { for (; p2 = p1->av_forw; p1 = p2) { if (p1->cylin <= bp->cylin && bp->cylin < p2->cylin || p1->cylin >= bp->cylin && bp->cylin > p2->cylin) break; } bp->av_forw = p2; p1->av_forw = bp; } if (rptab.d_active==0) rpstart(); spl0(); } rpstart() { register struct buf *bp; register int n; if ((bp = rptab.d_actf) == 0) return; rptab.d_active++; n = bp->b_dev.d_minor>>3; rpetab.e_aunit = &rpstat[n]; rpetab.e_aunit->io_ops++; blkacty =| (1<rpda = bp->trksec; devstart(bp, &RPADDR->rpca, bp->cylin, n); dk_busy =| 1<b_wcount>>5) & 03777; } rpintr() { register struct buf *bp; register int ctr; struct rpregs rpregs[0]; if (rptab.d_active == 0) return; blkacty =& ~(1<rpcs < 0) { /* error bit */ /* deverror(bp, RPADDR->rper, RPADDR->rpds); /**/ fmtblk(&rpetab,RPADDR,sizeof(rpregs[0])/2,bp); if(RPADDR->rpds & (SUFU|SUSI|HNF)) { RPADDR->rpcs.lobyte = HSEEK|GO; rpetab.e_aunit->io_misc++; ctr = 0; while ((RPADDR->rpds&SUSU) && --ctr); } RPADDR->rpcs = RESET|GO; rpetab.e_aunit->io_misc++; ctr = 0; while ((RPADDR->rpcs&READY) == 0 && --ctr); if (rptab.d_errcnt < 10) { if(rptab.d_errcnt++ == 0) logerr(&rpetab,E_FIRST); rpstart(); return; } bp->b_flags =| B_ERROR; } if(rpetab.e_emsg != NULL) logerr(&rpetab,E_RETRY); rptab.d_errcnt = 0; rptab.d_actf = bp->av_forw; bp->b_resid = RPADDR->rpwc; iodone(bp); rpstart(); } rpread(dev) { register nblks; nblks = rp_sizes[dev.d_minor & 07].nblocks; physio(rpstrategy, &rrpbuf, dev, B_READ, nblks); } rpwrite(dev) { register nblks; nblks = rp_sizes[dev.d_minor & 07].nblocks; physio(rpstrategy, &rrpbuf, dev, B_WRITE, nblks); } 0) logerr(&rpetab,E_FIRST); rpstart(); return; } bp->b_flags =| B_ERROR; } if(rpetab.e_emsg != NULL) logerr(&rpetab,E_RETRY); rptab.d_errcnt = 0; rptab.d_actf = bp->av_forw; bp->b_resid = RPADDR->rpwc; iodone(bp); rpstart(); } rpread(dev) { register nblks; nblks = rp_sizes[dev.d_minor & 07].nblocks; physio(rpstrategy, &rrpbuf, dev, B_READ, nblks); } rpwrite(dev) { register nblks; nblks = rp_sizes[d# /* */ /* * indirect driver for controlling tty. */ #include "../head/param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" #include "../head/proc.h" #include "../head/procx.h" syopen(dev, flag) { if(u.u_ttyp == NULL) { u.u_error = ENXIO; return; } (*cdevsw[u.u_ttyd.d_major].d_open)(u.u_ttyd, flag); } syread(dev) { (*cdevsw[u.u_ttyd.d_major].d_read)(u.u_ttyd); } sywrite(dev) { (*cdevsw[u.u_ttyd.d_major].d_write)(u.u_ttyd); } sysgtty(dev, flag) { (*cdevsw[u.u_ttyd.d_major].d_sgtty)(u.u_ttyd, flag); } param.h" #include "../head/conf.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" #include "../head/proc.h" #include "../head/procx.h" syopen(dev, flag) { if(u.u_ttyp == NULL) { u.u_error = ENXIO; return; } (*cdevsw[u.u_ttyd.d_major].d_open)(u.u_ttyd, flag); } syread(dev) { (*cdevsw[u.u_ttyd.d_major].d_read)(u.u_ttyd); } sywrite(dev) { (*cdevsw[u.u_ttyd.d_major].d_write)(u.u_ttyd); } sys# /* * TC-11 DECtape driver */ #include "../head/param.h" #include "../head/systm.h" #include "../head/conf.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" struct tcregs { int tccsr; int tccm; int tcwc; int tcba; int tcdt; }; #define NTC 8 #define NTCBLK 578 #define TCADDR 0177340 struct devtab tctab; char tcper[8]; struct iostat tcstat[NTC]; struct errtab tcetab { etabinit(E_BLK,NTC,TC,tcstat) }; #define TAPERR 0100000 #define TREV 04000 #define READY 0200 #define IENABLE 0100 #define UPS 0200 #define ENDZ 0100000 #define BLKM 02000 #define ILGOP 010000 #define SELERR 04000 #define SAT 0 #define RNUM 02 #define RDATA 04 #define SST 010 #define WDATA 014 #define GO 01 #define SFORW 1 #define SREV 2 #define SIO 3 tcopen(dev, flag) { if(dev.d_minor >= NTC) u.u_error = ENXIO; } tcclose(dev) { bflush(dev); tcper[dev&07] = 0; } tcstrategy(abp) struct buf *abp; { register struct buf *bp; bp = abp; if(bp->b_flags&B_PHYS) mapalloc(bp); if(tcper[bp->b_dev&07]) { bp->b_flags =| B_ERROR; iodone(bp); return; } if(bp->b_blkno >= NTCBLK) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } bp->av_forw = 0; spl6(); if (tctab.d_actf==0) tctab.d_actf = bp; else tctab.d_actl->av_forw = bp; tctab.d_actl = bp; if (tctab.d_active==0) tcstart(); spl0(); } tcstart() { register struct buf *bp; register int *tccmp, com; loop: tccmp = &TCADDR->tccm; if ((bp = tctab.d_actf) == 0) return; if(tcper[bp->b_dev&07]) { if((tctab.d_actf = bp->av_forw) == 0) (*tccmp).lobyte = SAT|GO; bp->b_flags =| B_ERROR; iodone(bp); goto loop; } if (((*tccmp).hibyte&07) != bp->b_dev.d_minor) (*tccmp).lobyte = SAT|GO; tctab.d_errcnt = 20; tctab.d_active = SFORW; tcetab.e_aunit = &tcstat[bp->b_dev.d_minor]; tcetab.e_aunit->io_misc++; com = (bp->b_dev.d_minor<<8) | IENABLE|RNUM|GO; if ((TCADDR->tccsr & UPS) == 0) { com =| TREV; tctab.d_active = SREV; } *tccmp = com; } tcintr() { register struct buf *bp; register int *tccmp; register int *tcdtp; struct tcregs tcregs[0]; tccmp = &TCADDR->tccm; tcdtp = &TCADDR->tccsr; bp = tctab.d_actf; blkacty =& ~(1<b_dev&07]++; tctab.d_errcnt = 0; } *tccmp =& ~TAPERR; if (--tctab.d_errcnt <= 0) {  bp->b_flags =| B_ERROR; goto done; } if(tctab.d_errcnt == 19) logerr(&tcetab,E_FIRST); if (*tccmp&TREV) { setforw: tctab.d_active = SFORW; *tccmp =& ~TREV; } else { setback: tctab.d_active = SREV; *tccmp =| TREV; } tcetab.e_aunit->io_misc++; (*tccmp).lobyte = IENABLE|RNUM|GO; return; } tcdtp = &TCADDR->tcdt; switch (tctab.d_active) { case SIO: done: if(tcetab.e_emsg != NULL) logerr(&tcetab,E_RETRY); tctab.d_active = 0; bp->b_resid = TCADDR->tcwc; if (tctab.d_actf = bp->av_forw) tcstart(); else TCADDR->tccm.lobyte = SAT|GO; iodone(bp); return; case SFORW: if (*tcdtp > bp->b_blkno) goto setback; if (*tcdtp < bp->b_blkno) goto setforw; *--tcdtp = bp->b_addr; /* core address */ *--tcdtp = bp->b_wcount; tccmp->lobyte = ((bp->b_xmem & 03) << 4) | IENABLE|GO | (bp->b_flags&B_READ?RDATA:WDATA); tctab.d_active = SIO; blkacty =| (1<io_ops++; return; case SREV: if (*tcdtp+3 > bp->b_blkno) goto setback; goto setforw; } } start(); else TCADDR->tccm.lobyte = SAT|GO; iodone(bp); return; case SFORW: if (*tcdtp > bp->b_blkno) goto setback; if (*tcdtp < bp->b_blkno) goto setforw; *--tcdtp = bp->b_addr; /* core address */ *--tcdtp = bp->b_wcount; tccmp->lobyte = ((bp->b_xmem & 03) << 4) | IENABLE|GO | (bp->b_flags&B_READ?RDATA:WDATA); tctab.d_active = SIO; blkacty =| (1<io_ops++; return; case SREV: if (*tcdtp+3 > bp->b_blkno) g# /* * TM tape driver * Conventions: * minor devices 0-3 rewind * minor devices 4-7 no rewind */ #include "../head/param.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/file.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/elog.h" struct tmregs { int tmer; int tmcs; int tmbc; int tmba; int tmdb; int tmrd; }; #define NTM 4 #define TMADDR 0172520 struct devtab tmtab; struct buf rtmbuf; struct buf ctmbuf; struct iostat tmstat[NTM]; struct errtab tmetab { etabinit(E_BLK,NTM,TM,tmstat) }; char t_openf[NTM]; char *t_blkno[NTM]; char *t_nxrec[NTM]; #define GO 01 #define RCOM 02 #define WCOM 04 #define WEOF 06 #define SFORW 010 #define SREV 012 #define WIRG 014 #define REW 016 #define DENS 060000 /* 9-channel */ #define IENABLE 0100 #define CRDY 0200 #define TUR 1 #define WRL 4 #define SELR 0100 #define GSD 010000 #define HARD 0102200 /* ILC, EOT, NXM */ #define EOF 0040000 #define NOP 0 #define SSEEK 01 #define SIO 02 #define SBACK 04 #define TCMD 010 #define SBAD 020 tmopen(dev, flag) { register int unit, ds, i; unit = dev.d_minor&03; if(unit >= NTM || t_openf[unit]) { u.u_error = ENXIO; return; } flag =& FWRITE; for(i = 0; i < 75; i++) { /* only wait 5 min for TUR */ t_blkno[unit] = 0; t_nxrec[unit] = 65535L; ds = tcommand(unit, NOP); if((ds&SELR)==0 || (flag && (ds&WRL)) || t_openf[unit]) { u.u_error = ENXIO; return; } if(ds&TUR) { if(u.u_error == 0) t_openf[unit]++; return; } sleep(&lbolt, -1); } u.u_error = ENXIO; } tmclose(dev, flag) { register int unit; unit = dev.d_minor&03; flag =& FWRITE; if (flag){ tcommand(unit, WEOF); tcommand(unit, WEOF); } if ((dev.d_minor&04) == 0) tcommand(unit, REW); else if(flag) tcommand(unit, SREV); t_openf[unit] = 0; } tcommand(unit, com) { register struct buf *bp; bp = &ctmbuf; spl5(); while(bp->b_flags&B_BUSY) { bp->b_flags =| B_WANTED; sleep(bp, PRIBIO); } spl0(); bp->b_flags = B_BUSY|B_READ; bp->b_dev = unit; bp->b_blkno = 0; bp->b_resid = com; tmstrategy(bp); iowait(bp); if(bp->b_flags&B_WANTED) wakeup(bp); bp->b_flags = 0; return(bp->b_resid); } tmstrategy(abp) struct buf *abp; { register struct buf *bp; register char **p; bp = abp; if(bp->b_flags&B_PHYS) mapalloc(bp); p = &t_nxrec[bp->b_dev.d_minor&03]; if (*p < bp->b_blkno || (*p == bp->b_blkno && bp->b_flags&B_READ)) { if (bp->b_flags&B_READ) bp->b_resid = bp->b_wcount; else { bp->b_flags =| B_ERROR; bp->b_error = ENXIO; } iodone(bp); return; } if ((bp->b_flags&B_READ)==0) *p = bp->b_blkno + 1; bp->av_forw = 0; spl5(); if (tmtab.d_actf==0) tmtab.d_actf = bp; else tmtab.d_actl->av_forw = bp; tmtab.d_actl = bp; if (tmtab.d_active==0) tmstart(); spl0(); } tmstart() { register struct buf *bp; register int com, unit; char *blkno; loop: if ((bp = tmtab.d_actf) == 0) return; unit = bp->b_dev.d_minor&03; com = (unit<<8); TMADDR->tmcs = com; /* gives unit time to be selected */ blkno = t_blkno[unit]; tmetab.e_aunit = &tmstat[unit]; if(bp == &ctmbuf) { if(bp->b_resid == NOP) { bp->b_resid = TMADDR->tmer; tmtab.d_actf = bp->av_forw; iodone(bp); goto loop; } tmtab.d_active = TCMD; tmetab.e_aunit->io_misc++; TMADDR->tmbc = 0; TMADDR->tmcs = com|bp->b_resid|DENS|IENABLE|GO; return; } if (t_openf[unit] < 0 || (TMADDR->tmcs & CRDY)==0) { if((t_openf[unit] != -2) || (bp->b_flags&B_READ)) { if (t_openf[unit] == -2) bp->b_resid = bp->b_wcount; else bp->b_flags =| B_ERROR; tmtab.d_actf = bp->av_forw; iodone(bp); goto loop; } } com =| DENS | ((bp->b_xmem & 03)<<4) | IENABLE ; if (blkno != bp->b_blkno) { tmtab.d_active = SSEEK; if (blkno < bp->b_blkno) { com =| SFORW|GO; TMADDR->tmbc = blkno - bp->b_blkno; } else { com =| SREV|GO; TMADDR->tmbc = bp->b_blkno - blkno; if(t_openf[unit] == -2) tmtab.d_active = SBACK; } tmetab.e_aunit->io_misc++; } else { tmtab.d_active = SIO; tmetab.e_aunit->io_ops++; blkacty =| (1<tmbc = bp->b_wcount << 1; TMADDR->tmba = bp->b_addr; /* core address */ com =| ((bp->b_flags&B_READ)? RCOM|GO: ((tmtab.d_errcnt)? WIRG|GO: WCOM|GO)); } TMADDR->tmcs = com; } tmintr() { register struct buf *bp; register int unit, state; struct tmregs tmregs[0]; if ((bp = tmtab.d_actf)==0) return; blkacty =& ~(1<b_dev.d_minor&03; if (TMADDR->tmcs < 0) { /* error bit */ while(TMADDR->tmrd & GSD) ; /* wait for gap shutdown */ if(state&(SSEEK|TCMD) || TMADDR->tmer&HARD) { t_openf[unit] = -1; state = SBAD; } else if((TMADDR->tmer&EOF) == 0) { /* soft errors */ if (tmtab.d_errcnt < 10) { fmtblk(&tmetab,TMADDR,sizeof(tmregs[0])/2,bp); if(tmtab.d_errcnt++ == 0) logerr(&tmetab,E_FIRST); t_blkno[unit]++; tmtab.d_active = 0; tmstart(); return; } else state = SBAD; } else if(bp != &rtmbuf) { /* EOF */ if(state&SBACK) t_openf[unit] = 1; else t_openf[unit] = -2; } if(state&SBAD) { bp->b_flags =| B_ERROR; fmtblk(&tmetab,TMADDR,sizeof(tmregs[0])/2,bp); } else TMADDR->tmbc = bp->b_wcount << 1; } if(state&(SIO|TCMD|SBAD)) { if(tmetab.e_emsg != NULL) logerr(&tmetab,E_RETRY); tmtab.d_errcnt = 0; t_blkno[unit]++; tmtab.d_actf = bp->av_forw; tmtab.d_active = 0; bp->b_resid = TMADDR->tmbc >> 1; iodone(bp); } else t_blkno[unit] = bp->b_blkno; tmstart(); } tmread(dev) { tmphys(dev); physio(tmstrategy, &rtmbuf, dev, B_READ, 0); } tmwrite(dev) { tmphys(dev); physio(tmstrategy, &rtmbuf, dev, B_WRITE, 0); } tmphys(dev) { register unit, a; unit = dev.d_minor&03; a = lshift(u.u_offset, -9); t_blkno[unit] = a; t_nxrec[unit] = ++a; } logerr(&tmetab,E_RETRY); tmtab.d_errcnt = 0; t_blkno[unit]++; tmtab.d_actf = bp->av_forw; tmtab.d_active = 0; bp->b_resid = TMADDR->tmbc >> 1; iodone(bp); } else t_blkno[unit] = bp->b_blkno; tmstart(); } tmread(dev) { tmphys(dev); physio(tmstrategy, &rtmbuf, dev, B_# /* */ /* * general TTY subroutines */ #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/tty.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/file.h" #include "../head/filex.h" #include "../head/reg.h" #include "../head/conf.h" int nltype; /* number of line disciplines */ char partab[]; #define SSPEED 7 /* standard speed: 300 baud */ #define DLDELAY 4 /* Extra delay for DL's (double buff) */ /* * Input mapping table-- if an entry is non-zero, when the * corresponding character is typed preceded by "\" the escape * sequence is replaced by the table value. Mostly used for * upper-case only terminals. */ char maptab[] { 000,000,000,000,CEOT,00,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,'|',000,'#',000,000,000,'`', '{','}',000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, '@',000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,000,000, 000,000,000,000,000,000,'~',000, 000,'A','B','C','D','E','F','G', 'H','I','J','K','L','M','N','O', 'P','Q','R','S','T','U','V','W', 'X','Y','Z',000,000,000,000,000, }; /* * The actual structure of a clist block manipulated by * getc and putc (mch.s) */ struct cblock { struct cblock *c_next; char info[6]; }; /* The character lists-- space for 6*NCLIST characters */ struct cblock cfree[NCLIST]; /* List head for unused character blocks. */ struct cblock *cfreelist; /* * structure of device registers for KL, DL, and DC * interfaces-- more particularly, those for which the * SSTART bit is off and can be treated by general routines * (that is, not DH). */ struct { int ttrcsr; int ttrbuf; int tttcsr; int tttbuf; }; /* * Routine to open a tty line. Initialize and wait * for carrier to come on. Establish a process * group for the distribution of quits and interrupts * from the tty. */ ttopen(dev, atp) struct tty *atp; { register struct tty *tp; register struct proc *pp; tp = atp; tp->t_state =| WOPEN; if ((tp->t_state&ISOPEN) == 0) { tp->t_erase = CERASE; tp->t_kill = CKILL; tp->t_speeds = SSPEED | (SSPEED<<8); tp->t_flags = ODDP|EVENP|ECHO; (*ctlsw[tp->t_dtype].d_param)(dev, tp); } else if (tp->t_state&XCLUDE && u.u_uid!=0) { u.u_error = EBUSY; return; } ttmopen(dev, tp); pp = u.u_procp; if(pp->p_pgrp == 0) { if(tp->t_pgrp) pp->p_pgrp = tp->t_pgrp; else { tp->t_pgrp = pp->p_pid; pp->p_pgrp = pp->p_pid; } u.u_ttyp = tp; u.u_ttyd = dev; } tp->t_state =& ~WOPEN; tp->t_state =| ISOPEN; } /* * Modem open for tty lines. Set up modem to answer phone * and transmit main carrier. Wait until carrier is received * from other side. */ ttmopen(dev, atp) struct tty *atp; { register struct tty *tp; register dtype; tp = atp; dtype = tp->t_dtype; (*ctlsw[dtype].d_mctl)(dev, TURNON|RQS); spl5(); if((*ctlsw[dtype].d_mctl)(dev, FSTATUS) & CARRIER) tp->t_state =| CARR_ON; else tp->t_state =& ~CARR_ON; while((tp->t_state&CARR_ON)==0) sleep(&tp->t_rawq, TTIPRI); spl0(); } /* * Close a tty line. */ ttclose(dev, atp) struct tty *atp; { register struct tty *tp; tp = atp; if (tp->t_state&ISOPEN) { if (tp->t_flags&HUPCL) (*ctlsw[tp->t_dtype].d_mctl)(dev, HUP); tp->t_state =& (CARR_ON|SSTART); tp->t_pgrp = 0; if(tp->t_state&CARR_ON) wflushtty(tp); else flushtty(tp); } } /* * Routine implementing the gtty system call. * Translate format and handle using ioctl. */ gtty() { u.u_arg[1] = u.u_arg[0]; u.u_arg[0] = ('t'<<8)|GTTY; ioctl(); } /* * The routine implementing the stty system call. * Translate format and handle using ioctl. */ stty() { u.u_arg[1] = u.u_arg[0]; u.u_arg[0] = ('t'<<8)|STTY; ioctl(); } /* * Routine implementing the ioctl system call. Check * legality and switch out to individual device routine. */ ioctl() { register struct file *fp; register struct inode *ip; register flag; if ((fp = getf(u.u_ar0[R0])) == NULL) return; ip = fp->f_inode; if ((ip->i_mode&IFMT) != IFCHR) { u.u_error = ENOTTY; return; } flag = fp->f_flag&(FREAD|FWRITE); (*cdevsw[ip->i_addr[0].d_major].d_sgtty)(ip->i_addr[0], flag); } /* * ioctl for line discipline devices. Handle setting and * fetching of line discipline. Switch out to line discipline * routines for actual work. */ ttioctl(dev, atp, flag) struct tty *atp; { register struct tty *tp; register int *v; register cmd; int word0; tp = atp; if (u.u_arg[0].hibyte != 't') { u.u_error = EBIOCTL; return; } v = u.u_arg[1]; u.u_arg[2] = flag; switch (cmd = u.u_arg[0].lobyte&0377) { case SET: case UNSET: u.u_error = EBIOCTL; break; /* * Get line discipline number */ case GETD: suword(v, tp->t_discp<<8); break; /* * Change to specified line discipline if not same * as current one. Execute subcommand. */ case CHNGD: word0 = fuword(v); if(word0.hibyte >= nltype) { u.u_error = EBIOCTL; break; } if (flag==0 && (tp->t_state&ISOPEN)==0) { tp->t_discp = word0.hibyte; break; } if (word0.hibyte != tp->t_discp) { (*linesw[tp->t_discp].l_sgtty)(dev, tp, UNSET); tp->t_discp = word0.hibyte; (*linesw[tp->t_discp].l_sgtty)(dev, tp, SET); break; } default: (*linesw[tp->t_discp].l_sgtty)(dev, tp, cmd); } } /* * Wait for output to drain, then flush input waiting. */ wflushtty(atp) struct tty *atp; { register struct tty *tp; tp = atp; spl5(); while (tp->t_outq.c_cc) { tp->t_state =| ASLEEP; sleep(&tp->t_outq, TTOPRI); } flushtty(tp); spl0(); } /* * Initialize clist by freeing all character blocks, then count * number of character devices, number of line disciplines and * number of terminal subdisciplines. (Once-only routine) */ cinit() { register int ccp; register struct cblock *cp; register struct cdevsw *cdp; struct linesw *lsp; ccp = cfree; for (cp=(ccp+07)&~07; cp <= &cfree[NCLIST-1]; cp++) { cp->c_next = cfreelist; cfreelist = cp; } ccp = 0; for(cdp = cdevsw; cdp->d_open; cdp++) ccp++; nchrdev = ccp; ccp = 0; for(lsp = linesw; lsp->l_open; lsp++) ccp++; nltype = ccp; } /* * flush all TTY queues */ flushtty(atp) struct tty *atp; { register struct tty *tp; register int sps; tp = atp; while (getc(&tp->t_canq) >= 0); while (getc(&tp->t_outq) >= 0); wakeup(&tp->t_rawq); wakeup(&tp->t_outq); sps = PS->integ; spl5(); while (getc(&tp->t_rawq) >= 0); tp->t_delct = 0; PS->integ = sps; } /* * transfer raw input list to canonical list, * doing erase-kill processing and handling escapes. * It waits until a full line has been typed in cooked mode, * or until any character has been typed in raw mode. */ canon(atp) struct tty *atp; { register char *bp; char *bp1; register struct tty *tp; register int c; int mc; tp = atp; spl5(); while ((tp->t_flags&RAW)==0 && tp->t_delct==0 || (tp->t_flags&RAW)!=0 && tp->t_rawq.c_cc==0) { if ((tp->t_state&CARR_ON)==0) { spl0(); return(0); } sleep(&tp->t_rawq, TTIPRI); } spl0(); loop: bp = &canonb[2]; while ((c=getc(&tp->t_rawq)) >= 0) { if ((tp->t_flags&RAW)==0) { if (c==0377) { tp->t_delct--; break; } if (bp[-1]!='\\') { if (c==tp->t_erase) { if (bp > &canonb[2]) bp--; continue; } if (c==tp->t_kill) goto loop; if (c==CEOT) continue; } else { mc = maptab[c]; if (c==tp->t_erase || c==tp->t_kill) mc = c; if (mc && (mc==c || (tp->t_flags&LCASE))) { if (bp[-2] != '\\')  c = mc; bp--; } } } *bp++ = c; if (bp>=canonb+CANBSIZ) break; } bp1 = bp; bp = &canonb[2]; c = &tp->t_canq; while (bpt_flags; if((tp->t_state&ISOPEN)==0 || (c & OVERRUN)) { wakeup(&tp->t_rawq); return; } if (c&FRERROR) /* break */ if (t_flags&RAW) c = 0; /* null (for getty) */ else c = 0177; /* DEL (intr) */ if (c&PERROR) if ((t_flags&(EVENP|ODDP))==EVENP || (t_flags&(EVENP|ODDP))==ODDP ) return; if((c =& 0177) == '\r' && t_flags & CRMOD) c = '\n'; if((t_flags&RAW)==0) { if(c==CQUIT || c==CINTR) { signal(tp->t_pgrp, c==CINTR? SIGINT:SIGQIT); flushtty(tp); return; } else if(c==CXSTOP) { if(tp->t_state&XMTSTOP) { tp->t_state =& ~XMTSTOP; ttstart(tp); } else tp->t_state =| XMTSTOP; return; } } if (tp->t_rawq.c_cc>TTYHOG) { flushtty(tp); return; } if (t_flags&LCASE && c>='A' && c<='Z') c =+ 'a'-'A'; putc(c, &tp->t_rawq); if (t_flags&RAW || (c=='\n' || c==CEOT)) { wakeup(&tp->t_rawq); if ((t_flags&RAW)==0 && putc(0377, &tp->t_rawq)==0) tp->t_delct++; } if (t_flags&ECHO) { ttyoutput(c, tp); tp->t_state =& ~XMTSTOP; if (c==tp->t_kill && (t_flags&RAW)==0) ttyoutput('\n', tp); ttstart(tp); } } /* * put character on TTY output queue, adding delays, * expanding tabs, and handling the CR/NL bit. * It is called both from the top half for output, and from * interrupt level for echoing. * The arguments are the character and the tty structure. */ ttyoutput(ac, tp) struct tty *tp; { register int c; register struct tty *rtp; register char *colp; int ctype; tk_nout =+ 1; rtp = tp; c = ac & 0177; /* * Ignore EOT in normal mode to avoid hanging up * certain terminals. * In raw mode dump the char unchanged. */ if(c == CEOT && (rtp->t_flags&RAW) == 0) return; /* * Turn tabs to spaces as required */ if (c=='\t' && rtp->t_flags&XTABS) { do ttyoutput(' ', rtp); while (rtp->t_col&07); return; } /* * for upper-case-only terminals, * generate escapes. */ if (rtp->t_flags&LCASE) { colp = "({)}!|^~'`"; while(*colp++) if(c == *colp++) { ttyoutput('\\', rtp); c = colp[-2]; break; } if ('a'<=c && c<='z') c =+ 'A' - 'a'; } /* * turn to if desired. */ if (c=='\n' && rtp->t_flags&CRMOD) ttyoutput('\r', rtp); putc(c, &rtp->t_outq); /* * Calculate delays. * The numbers here represent clock ticks * and are not necessarily optimal for all terminals. * The delays are indicated by characters above 0200. * In raw mode there are no delays and the * transmission path is 8 bits wide. */ colp = &rtp->t_col; ctype = partab[c]; c = 0; switch (ctype&077) { /* ordinary */ case 0: (*colp)++; /* non-printing */ case 1: break; /* backspace */ case 2: if (*colp) (*colp)--; break; /* newline */ case 3: ctype = (rtp->t_flags >> 8) & 03; if(ctype == 1) { /* tty 37 */ if (*colp) c = max((*colp>>4) + 3, 6); } else if(ctype == 2) { c = 2; } else if(ctype == 3) { /* TTY 40 printer */ if(*colp <= 34) { if(*colp) c = (34 - *colp)>>1; else c = 2; } } *colp = 0; break; /* tab */  case 4: ctype = (rtp->t_flags >> 10) & 03; if(ctype == 1) { /* tty 37 */ c = 1 - (*colp | ~07); if(c < 5) c = 0; } *colp =| 07; (*colp)++; break; /* vertical motion */ case 5: if(rtp->t_flags & VTDELAY) /* tty 37 */ c = 0177; break; /* carriage return */ case 6: ctype = (rtp->t_flags >> 12) & 03; if(ctype == 1) { /* tn 300 */ c = 4; } else if(ctype == 2) { c = 4; } else if(ctype == 3) { c = 10; } *colp = 0; } if(c) putc(c|0200, &rtp->t_outq); } /* * Restart typewriter output following a delay * timeout. * The name of the routine is passed to the timeout * subroutine and it is called during a clock interrupt. */ ttrstrt(atp) { register struct tty *tp; tp = atp; tp->t_state =& ~TIMEOUT; ttstart(tp); } /* * Start output on the typewriter. It is used from the top half * after some characters have been put on the output queue, * from the interrupt routine to transmit the next * character, and after a timeout has finished. * If the SSTART bit is off for the tty the work is done here, * using the protocol of the single-line interfaces (KL, DL, DC); * otherwise the address word of the tty structure is * taken to be the name of the device-dependent startup routine. */ ttstart(atp) struct tty *atp; { register int *addr, c; int sps; register struct tty *tp; struct { int (*func)(); }; tp = atp; addr = tp->t_addr; if (tp->t_state&SSTART) { (*addr.func)(tp); return; } sps = PS->integ; spl5(); if ((addr->tttcsr&DONE)==0 || tp->t_state&TIMEOUT) goto out; if((c = (*linesw[tp->t_discp].l_xmtd)(tp))< 0) addr->tttbuf = c; else if (c&CTOUT) { timeout(ttrstrt, tp, (c&0177) + DLDELAY); tp->t_state =| TIMEOUT; } out: PS->integ = sps; } /* * Get next character for transmission to a tty. * Accessed via l_xmtd entry in linesw table in conf.c */ ttxmtd(atp) struct tty *atp; { register struct tty *tp; register c; tp = atp; if(tp->t_state&XMTSTOP || (c = getc(&tp->t_outq)) < 0) return(0); if (c<=0177) c =| CPRES|(partab[c]&0200); else c =| CTOUT; /* * If the writer was sleeping on output overflow, * wake him when low tide is reached. */ if (tp->t_outq.c_cc<=TTLOWAT && tp->t_state&ASLEEP) { tp->t_state =& ~ASLEEP; wakeup(&tp->t_outq); } return(c); } /* * Called from device's read routine after it has * calculated the tty-structure given as argument. * The pc is backed up for the duration of this call. * In case of a caught interrupt, an RTI will re-execute. */ ttread(atp) struct tty *atp; { register struct tty *tp; tp = atp; if ((tp->t_state&CARR_ON)==0) return; if (tp->t_canq.c_cc || canon(tp)) while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0); } /* * Called from the device's write routine after it has * calculated the tty-structure given as argument. */ ttwrite(atp) struct tty *atp; { register struct tty *tp; register int c; tp = atp; if ((tp->t_state&CARR_ON)==0) return; while ((c=cpass())>=0) { spl5(); while (tp->t_outq.c_cc > TTHIWAT) { ttstart(tp); tp->t_state =| ASLEEP; sleep(&tp->t_outq, TTOPRI); } spl0(); ttyoutput(c, tp); } ttstart(tp); } /* * Common code for tty line disciplines */ ttstty(dev, atp, cmd) struct tty *atp; { register struct tty *tp; register int *v; int word1; tp = atp; v = u.u_arg[1]; switch(cmd) { case UNSET: ttclose(dev, tp); break; case SET: ttopen(dev, tp); case CHNGD: break; case STTY: wflushtty(tp); case STTYNF: tp->t_speeds = fuword(v++); tp->t_flags = (fuword(++v))&077777; if (tp->t_speeds.lobyte == 0) { tp->t_flags =| HUPCL; (*ctlsw[tp->t_dtype].d_mctl)(dev, HUP); break; } (*ctlsw[tp->t_dtype].d_param)(dev, tp); break; case GTTY: suword(v++, tp->t_speeds); suword(++v, tp->t_flags); break; /* * Prevent opens on channel. */ case XCLD: tp->t_state =| XCLUDE; break; case FEK: word1.lobyte = tp->t_erase; word1.hibyte = tp->t_kill; suword(++v, word1); break; case SEK: word1 = fuword(++v); tp->t_erase = word1.lobyte; tp->t_kill = word1.hibyte; break; default: u.u_error = EBIOCTL; } } /* * Modem transition handling. If carrier is * off and open is not in progress, hang up the * local dataset and signal a hangup. */ ttmt(atp, status) struct tty *atp; { register struct tty *tp; register action; tp = atp; action = 0; wakeup(&tp->t_rawq); if ((status&CARRIER)==0) { if ((tp->t_state&WOPEN)==0) { signal(tp->t_pgrp, SIGHUP); action = DISABLE; flushtty(tp); } tp->t_state =& ~CARR_ON; } else tp->t_state =| CARR_ON;  return(action); } ult: u.u_error = EBIOCTL; } } /* * Modem transition handling. If carrier is * off and open is not in progress, hang up the * local dataset and signal a hangup. */ ttmt(atp, status) struct tty *atp; { register struct tty *tp; register action; tp = atp; action = 0; wakeup(&tp->t_rawq); if ((status&CARRIER)==0) { if ((tp->t_state&WOPEN)==0) { signal(tp->t_pgrp, SIGHUP); action = DISABLE; flushtty(tp); } tp->t_state =& ~CARR_ON; } else tp->t_state =| CARR_ON; # /* * link editor * R 1.5 7/28/76 */ #define SIGINT 2 #define ARCMAGIC 0177545 #define FMAGIC 0407 #define NMAGIC 0410 #define IMAGIC 0411 #define EXTERN 040 #define UNDEF 00 #define ABS 01 #define TEXT 02 #define DATA 03 #define BSS 04 #define COMM 05 /* internal use only */ #define RABS 00 #define RTEXT 02 #define RDATA 04 #define RBSS 06 #define REXT 010 #define RELFLG 01 #define NROUT 256 #define NSYM 807 #define NSYMPR 500 #define RONLY 0400 char premeof[] "Premature EOF"; struct page { int nuser; int bno; int nibuf; int buff[256]; } page[2]; struct { int nuser; int bno; } fpage; struct stream { int *ptr; int bno; int nibuf; int size; struct page *pno; }; struct stream text; struct stream reloc; struct archdr { char aname[14]; int atime[2]; char auid, agid; int amode; int asize[2]; } archdr; struct filhdr { int fmagic; int tsize; int dsize; int bsize; int ssize; int entry; int loadpt; /* relocation origin of start of text */ int relflg; } filhdr; struct liblist { int off; int bno; }; struct liblist liblist[NROUT]; struct liblist *libp { &liblist[0] }; struct symbol { char sname[8]; char stype; char spad; int svalue; }; struct symbol cursym; struct symbol symtab[NSYM]; struct symbol *hshtab[NSYM+2]; struct symbol *symp { symtab }; struct symbol **local[NSYMPR]; struct symbol *p_etext; struct symbol *p_edata; struct symbol *p_end; struct symbol *entrypt; int entryval; /* 1'st entry value defined in input */ int xflag; /* discard local symbols */ int Xflag; /* discard locals starting with 'L' */ int Sflag; /* discard all except locals and globals*/ int rflag; /* preserve relocation bits, don't define common */ int arflag; /* original copy of rflag */ int sflag; /* discard all symbols */ int nflag; /* pure procedure */ int dflag; /* define common even with rflag */ int iflag; /* I/D space separated */ int ofilfnd; char *ofilename "l.out"; int infil; char *filname; int tsize; int dsize; int bsize; int ssize; int nsym; int torigin; int dorigin; int borigin; int ctrel; int cdrel; int cbrel; int errlev; int delarg 4; char tfname[] "/tmp/lxyyyyy"; int toutb[259]; int doutb[259]; int troutb[259]; int droutb[259]; int soutb[259]; struct symbol **lookup(); struct symbol **slookup(); main(argc, argv) char **argv; { extern int delexit(); register c; register char *ap, **p; struct symbol **hp; if ((signal(SIGINT, 1) & 01) == 0) signal(SIGINT, delexit); if (argc == 1) exit(4); p = argv + 1; for (c = 1; c= argc) error(1, "Bad output file"); ofilename = *p++; ofilfnd++; continue; case 'u': case 'e': if (++c >= argc) error(1, "Bad 'use' or 'entry'"); if (*(hp = slookup(*p++)) == 0) { *hp = symp; enter(); } if (ap[1]=='e') entrypt = *hp; continue; case 'b': if(++c >= argc || ap[2] ) error(1, "Bad load point"); torigin = ( otoi( *p++ ) + 01 ) & ~01; continue; case 'l': break; case 'x': xflag++; continue; case 'X': Xflag++; continue; case 'S': Sflag++; continue; case 'r': rflag++; arflag++; continue; case 's': sflag++; xflag++; continue; case 'n': nflag++; continue; case 'd': dflag++; continue; case 'i': iflag++; continue; } load1arg(ap); close(infil); } filname = 0; middle(); setupout(); p = argv+1; libp = liblist; for (c=1; cbno = -1; libp++; return; } mget(&archdr, sizeof archdr); if (load1(1, nbno, noff + (sizeof archdr) / 2)) { libp->bno = nbno; libp->off = noff; libp++; } noff =+ ((archdr.asize[1]&0777)+sizeof(archdr)+1) >> 1; nbno =+ (archdr.asize[1] >> 9) & 0177; nbno =+ (archdr.asize[0]) << 7; nbno =+ noff >> 8; noff =& 0377; } } load1(libflg, bno, off) { register struct symbol *sp, **hp, ***cp; struct symbol *ssymp; int ndef, nloc, type, mtype; readhdr(bno, off); ctrel =+ tsize; cdrel =+ dsize; cbrel =+ bsize; if (filhdr.entry && entryval==0 ) entryval = filhdr.entry + ctrel; ndef = 0; nloc = sizeof cursym; cp = local; ssymp = symp; if ((filhdr.relflg&RELFLG)==1) { error(0, "No relocation bits"); return(0); } off =+ (sizeof filhdr)/2 + filhdr.tsize + filhdr.dsize; dseek(&text, bno, off, filhdr.ssize); while (text.size > 0) { mget(&cursym, sizeof cursym); type = cursym.stype; if (Sflag) { mtype = type&037; if (mtype==1 || mtype>4) { continue; } } if ((type&EXTERN)==0) { if (Xflag==0 || cursym.sname[0]!='L') nloc =+ sizeof cursym;  continue; } symreloc(); hp = lookup(); if ((sp = *hp) == 0) { *hp = enter(); *cp++ = hp; continue; } if (sp->stype != EXTERN+UNDEF) continue; if (cursym.stype == EXTERN+UNDEF) { if (cursym.svalue > sp->svalue) sp->svalue = cursym.svalue; continue; } if (sp->svalue != 0 && cursym.stype == EXTERN+TEXT) continue; ndef++; sp->stype = cursym.stype; sp->svalue = cursym.svalue; } if (libflg==0 || ndef) { tsize =+ filhdr.tsize; dsize =+ filhdr.dsize; bsize =+ filhdr.bsize; ssize =+ nloc; return(1); } /* * No symbols defined by this library member. * Rip out the hash table entries and reset the symbol table. */ symp = ssymp; while (cp > local) **--cp = 0; return(0); } middle() { register struct symbol *sp; register t, csize; int nund, corigin; p_etext = *slookup("_etext"); p_edata = *slookup("_edata"); p_end = *slookup("_end"); /* * If there are any undefined symbols, save the relocation bits. */ if (rflag==0) for (sp=symtab; spstype==EXTERN+UNDEF && sp->svalue==0 && sp!=p_end && sp!=p_edata && sp!=p_etext) { rflag++; dflag = 0; nflag = 0; iflag = 0; sflag = 0; break; } /* * Assign common locations. */ csize = 0; if (dflag || rflag==0) { ldrsym(p_etext, tsize, EXTERN+TEXT); ldrsym(p_edata, dsize, EXTERN+DATA); ldrsym(p_end, bsize, EXTERN+BSS); for (sp=symtab; spstype==EXTERN+UNDEF && (t=sp->svalue)!=0) { t = (t+1) & ~01; sp->svalue = csize; sp->stype = EXTERN+COMM; csize =+ t; } } /* * Now set symbols to their final value */ if (nflag || iflag) tsize = (tsize + 077) & ~077; dorigin = torigin + tsize; if (nflag) dorigin = (dorigin+017777) & ~017777; if (iflag) dorigin = 0; corigin = dorigin + dsize; borigin = corigin + csize; nund = 0; for (sp=symtab; spstype) { case EXTERN+UNDEF: errlev =| 01; if (arflag==0 && sp->svalue==0) { if (nund==0) printf("Undefined:\n"); nund++; printf("%.8s\n", sp->sname); } continue; case EXTERN+ABS: default: continue; case EXTERN+TEXT: sp->svalue =+ torigin; continue; case EXTERN+DATA: sp->svalue =+ dorigin; continue; case EXTERN+BSS: sp->svalue =+ borigin; continue; case EXTERN+COMM: sp->stype = EXTERN+BSS; sp->svalue =+ corigin; continue; } if (sflag || xflag) ssize = 0; bsize =+ csize; nsym = ssize / (sizeof cursym); } ldrsym(asp, val, type) struct symbol *asp; { register struct symbol *sp; if ((sp = asp) == 0) return; if (sp->stype != EXTERN+UNDEF || sp->svalue) { printf("%.8s: ", sp->sname); error(0, "Multiply defined"); return; } sp->stype = type; sp->svalue = val; } setupout() { register char *p; register pid; struct symbol *ep; if ((toutb[0] = creat(ofilename, 0666)) < 0) error(1, "Can't write output"); pid = getpid(); for (p = &tfname[12]; p > &tfname[7];) { *--p = (pid&07) + '0'; pid =>> 3; } tcreat(doutb, 'a'); if (sflag==0 || xflag==0) tcreat(soutb, 'b'); if (rflag) { tcreat(troutb, 'c'); tcreat(droutb, 'd'); } filhdr.fmagic = FMAGIC; if (nflag) filhdr.fmagic = NMAGIC; if (iflag) filhdr.fmagic = IMAGIC; filhdr.tsize = tsize; filhdr.dsize = dsize; filhdr.bsize = bsize; filhdr.ssize = sflag? 0: (ssize + (sizeof cursym)*(symp-symtab)); filhdr.entry = 0; if (ep = entrypt) { if (ep->stype!=EXTERN+TEXT) error(0, "Entry point not in text"); else filhdr.entry = ep->svalue | 01; } else if (entryval != 0) filhdr.entry = entryval + torigin; filhdr.loadpt = torigin; filhdr.relflg = (rflag==0); mput(toutb, &filhdr, sizeof filhdr); return; } tcreat(buf, letter) int *buf; { tfname[6] = letter; if ((buf[0] = creat(tfname, RONLY)) < 0) error(1, "Can't create temp"); } load2arg(acp) char *acp; { register char *cp; register struct liblist *lp; cp = acp; if (getfile(cp) == 0) { while (*cp) cp++; while (cp >= acp && *--cp != '/'); mkfsym(++cp); load2(0, 0); return; } for (lp = libp; lp->bno != -1; lp++) { dseek(&text, lp->bno, lp->off, sizeof archdr); mget(&archdr, sizeof archdr); mkfsym(archdr.aname); load2(lp->bno, lp->off + (sizeof archdr) / 2); } libp = ++lp; } load2(bno, off) { register struct symbol *sp; register int *lp, symno; int type, mtype; readhdr(bno, off); ctrel =+ torigin; cdrel =+ dorigin; cbrel =+ borigin; /* * Reread the symbol table, recording the numbering * of symbols for fixing external references. */ lp = local; symno = -1; off =+ (sizeof filhdr)/2; dseek(&text, bno, off+filhdr.tsize+filhdr.dsize, filhdr.ssize); while (text.size > 0) { symno++; mget(&cursym, sizeof cursym); symreloc(); type = cursym.stype; if (Sflag) { mtype = type&037; if (mtype==1 || mtype>4) continue; } if ((type&EXTERN) == 0) { if (!sflag&&!xflag&&(!Xflag||cursym.sname[0]!='L')) mput(soutb, &cursym, sizeof cursym); continue; } if ((sp = *lookup()) == 0) error(1, "internal error: symbol not found"); if (cursym.stype == EXTERN+UNDEF) { if (lp >= &local[NSYMPR]) error(1, "Local symbol overflow"); *lp++ = symno; *lp++ = sp; continue; } if (cursym.stype!=sp->stype || cursym.svalue!=sp->svalue) { printf("%.8s: ", cursym.sname); error(0, "Multiply defined"); } } dseek(&text, bno, off, filhdr.tsize); dseek(&reloc, bno, off+(filhdr.tsize+filhdr.dsize)/2, filhdr.tsize); load2td(lp, ctrel, toutb, troutb); dseek(&text, bno, off+(filhdr.tsize/2), filhdr.dsize); dseek(&reloc, bno, off+filhdr.tsize+(filhdr.dsize/2), filhdr.dsize); load2td(lp, cdrel, doutb, droutb); torigin =+ filhdr.tsize; dorigin =+ filhdr.dsize; borigin =+ filhdr.bsize; } load2td(lp, creloc, b1, b2) int *lp; { register r, t; register struct symbol *sp; for (;;) { /* * The pickup code is copied from "get" for speed. */ if (--text.size <= 0) { if (text.size < 0) break; text.size++; t = get(&text); } else if (--text.nibuf < 0) { text.nibuf++; text.size++; t = get(&text); } else t = *text.ptr++; if (--reloc.size <= 0) { if (reloc.size < 0) error(1, "Relocation error"); reloc.size++; r = get(&reloc); } else if (--reloc.nibuf < 0) { reloc.nibuf++; reloc.size++; r = get(&reloc); } else r = *reloc.ptr++; switch (r&016) { case RTEXT: t =+ ctrel; break; case RDATA: t =+ cdrel; break; case RBSS: t =+ cbrel; break; case REXT: sp = lookloc(lp, r); if (sp->stype==EXTERN+UNDEF) { r = (r&01) + ((nsym+(sp-symtab))<<4) + REXT; break; } t =+ sp->svalue; r = (r&01) + ((sp->stype-(EXTERN+ABS))<<1); break; } if (r&01) t =- creloc; putw(t, b1); if (rflag) putw(r, b2); } } finishout() { register n, *p; if (nflag||iflag) { n = torigin; while (n&077) { n =+ 2; putw(0, toutb); if (rflag) putw(0, troutb); } } copy(doutb, 'a'); if (rflag) { copy(troutb, 'c'); copy(droutb, 'd'); } if (sflag==0) { if (xflag==0) copy(soutb, 'b'); for (p=symtab; p < symp;) putw(*p++, toutb); } fflush(toutb); close(toutb[0]); if (!ofilfnd) { unlink("a.out"); link("l.out", "a.out"); ofilename = "a.out"; } delarg = errlev; delexit(); } delexit() { register c; unlink("l.out"); for (c = 'a'; c <= 'd'; c++) { tfname[6] = c; unlink(tfname); } if (delarg==0) chmod(ofilename, 0777); exit(delarg); } copy(buf, c) int *buf; { register f, *p, n; fflush(buf); close(buf[0]); tfname[6] = c; f = open(tfname, 0); while ((n = read(f, doutb, 512)) > 1) { n =>> 1; p = doutb; do putw(*p++, toutb); while (--n); } close(f); } mkfsym(s) char *s; { if (sflag || xflag) return; cp8c(s, cursym.sname); cursym.stype = 037; cursym.svalue = torigin; mput(soutb, &cursym, sizeof cursym); } mget(aloc, an) int *aloc; { register *loc, n; register *p; n = an; n =>> 1; loc = aloc; if ((text.nibuf =- n) >= 0) { if ((text.size =- n) > 0) { p = text.ptr; do *loc++ = *p++; while (--n); text.ptr = p; return; } else text.size =+ n; } text.nibuf =+ n; do { *loc++ = get(&text); } while (--n); } mput(buf, aloc, an) int *aloc; { register *loc; register n; loc = aloc; n = an>>1; do { putw(*loc++, buf); } while (--n); } dseek(asp, ab, o, s) { register struct stream *sp; register struct page *p; register b; int n; sp = asp; b = ab + ((o>>8) & 0377); o =& 0377; --sp->pno->nuser; if ((p = &page[0])->bno!=b && (p = &page[1])->bno!=b) if (p->nuser==0 || (p = &page[0])->nuser==0) { if (page[0].nuser==0 && page[1].nuser==0) if (page[0].bno < page[1].bno) p = &page[0]; p->bno = b; seek(infil, b, 3); if ((n = read(infil, p->buff, 512)>>1) < 0) n = 0; p->nibuf = n; } else error(1, "No pages"); ++p->nuser; sp->bno = b; sp->pno = p; sp->ptr = p->buff + o; if (s != -1) sp->size = (s>>1) & 077777; if ((sp->nibuf = p->nibuf-o) <= 0) sp->size = 0; } get(asp) struct stream *asp; { register struct stream *sp; sp = asp; if (--sp->nibuf < 0) { dseek(sp, sp->bno+1, 0, -1); --sp->nibuf; } if (--sp->size <= 0) { if (sp->size < 0) error(1, premeof); ++fpage.nuser; --sp->pno->nuser; sp->pno = &fpage; } return(*sp->ptr++); } getfile(acp) char *acp; { register char *cp; register c; cp = acp; archdr.aname[0] = '\0'; filname = cp; if (cp[0]=='-' && cp[1]=='l') { if(cp[2] == '\0') cp = "-la"; filname = "/usr/lib/libxxxxxxxxxxxxxxx"; for(c=0; cp[c+2]; c++) filname[c+12] = cp[c+2]; filname[c+12] = '.'; filname[c+13] = 'a'; filname[c+14] = '\0'; if ((infil = open(filname+4, 0)) >= 0) { filname =+ 4; goto OK; } } if ((infil = open(filname, 0)) < 0) error(1, "cannot open"); OK: page[0].bno = page[1].bno = -1; page[0].nuser = page[1].nuser = 0; text.pno = reloc.pno = &fpage; fpage.nuser = 2; dseek(&text, 0, 0, 2); if (text.size <= 0) error(1, premeof); return(get(&text) == ARCMAGIC); } struct symbol **lookup() { int i; register struct symbol **hp; register char *cp, *cp1; i = 0; for (cp=cursym.sname; cp < &cursym.sname[8];) i = (i<<1) + *cp++; for (hp = &hshtab[(i&077777)%NSYM+2]; *hp!=0;) { cp1 = (*hp)->sname; for (cp=cursym.sname; cp < &cursym.sname[8];) if (*cp++ != *cp1++) goto no; break; no: if (++hp >= &hshtab[NSYM+2]) hp = hshtab; } return(hp); } struct symbol **slookup(s) char *s; { cp8c(s, cursym.sname); cursym.stype = EXTERN+UNDEF; cursym.svalue = 0; return(lookup()); } enter() { register struct symbol *sp; if ((sp=symp) >= &symtab[NSYM]) error(1, "Symbol table overflow"); cp8c(cursym.sname, sp->sname); sp->stype = cursym.stype; sp->svalue = cursym.svalue; symp++; return(sp); } symreloc() { switch (cursym.stype) { case TEXT: case EXTERN+TEXT: cursym.svalue =+ ctrel; return; case DATA: case EXTERN+DATA: cursym.svalue =+ cdrel; return; case BSS: case EXTERN+BSS: cursym.svalue =+ cbrel; return; case EXTERN+UNDEF: return; } if (cursym.stype&EXTERN) cursym.stype = EXTERN+ABS; } error(n, s) char *s; { if (filname) { printf("%s", filname); if (archdr.aname[0]) printf("(%.14s)", archdr.aname); printf(": "); } printf("%s\n", s); if (n)  delexit(); errlev = 2; } lookloc(alp, r) { register int *clp, *lp; register sn; lp = alp; sn = (r>>4) & 07777; for (clp=local; clp 0) { yyolsp = lsp; if (yyextra[*yyfnd]) { while (yyback((*lsp)->%sstops, -*yyfnd) != 1 && lsp>yylstate) { lsp-main(){ yylex(); cexit(); } int c; c = getchar(); if (c== '\n') yylineno++; return(c); } ch-yytext+1; yytext[yyleng] = 0; return(*yyfnd++); } unput(*yylastch); } if (yytext[0] == 0) return(0); output(yyprevious = input()); yylastch=yytext; goto loop; } yyback(p, m) int *p; { if (p==0) return(0); while (*p) { if (*p++ == m) return(1); } return(0); } *yyfnd > 0) { yyolsp = lsp; if (yyextra[*yyfnd]) { while (yyback((*lsp)->%sstops, -*yyfnd) != 1 && lsp>yylstate) { lsp-output(c) { putchar(c); } int c; c = getchar(); if (c== '\n') yylineno++; return(c); } ch-yytext+1; yytext[yyleng] = 0; return(*yyfnd++); } unput(*yylastch); } if (yytext[0] == 0) return(0); output(yyprevious = input()); yylastch=yytext; goto loop; } yyback(p, m) int *p; { if (p==0) return(0); while (*p) { if (*p++ == m) return(1); } return(0); } *yyfnd > 0) { yyolsp = lsp; if (yyextra[*yyfnd]) { while (yyback((*lsp)->%sstops, -*yyfnd) != 1 && lsp>yylstate) { lsp-extern struct {int *yyaa, *yybb, *yystops;} *yylstate [], **yylsp, **yyolsp; extern int yyprevious , *yyfnd, yyextra[]; extern char yytext[]; extern int yyleng; yyreject () { int k; char *p; for( ; yylsp < yyolsp; yylsp++) yytext[yyleng++] = input(); if (*yyfnd) return(yyracc(*yyfnd++)); while (yylsp-- > yylstate) { unput(yytext[yyleng-1]); yytext[--yyleng] = 0; if (*yylsp != 0 && (yyfnd= (*yylsp)->yystops) && *yyfnd > 0) return(yyracc(*yyfnd++)); } if (yytext[0] == 0) return(0); output(yyprevious = input()); yyleng=0; return(-1); } yyracc(m) { yyolsp = yylsp; if (yyextra[m]) { while (yyback((*yylsp)->yystops, -m) != 1 && yylsp>yylstate) { yylsp--; unput(yytext[--yyleng]); } } yyprevious = yytext[yyleng-1]; yytext[yyleng] = 0; return(m); } fnd) return(yyracc(*yyfnd++)); while (yylsp-- > yylstate) { unput(yytext[yyleng-1]); yytext[--yyleng] = 0; if (*yylsp != 0 && (yyfnd= (*yylsp)->yystops) && *yyfnd > 0) return(yyracc(*yyfnd++)); } if (yytext[0] == 0) return(0); output(yypreviouunput(c) { extern int cin, yylineno; if (c== '\n') yylineno--; return(ungetc(c,cin)); } yyback((*yylsp)->yystops, -m) != 1 && yylsp>yylstate) { yylsp--; unput(yytext[--yyleng]); } } yyprevious = yytext[yyleng-1]; yytext[yyleng] = 0; return(m); } fnd) return(yyracc(*yyfnd++)); while (yylsp-- > yylstate) { unput(yytext[yyleng-1]); yytext[--yyleng] = 0; if (*yylsp != 0 && (yyfnd= (*yylsp)->yystops) && *yyfnd > 0) return(yyracc(*yyfnd++)); } if (yytext[0] == 0) return(0); output(yypreviouyyless(x) { extern char yytext[]; char *lastch, *ptr; extern int yyleng; int yyprevious; lastch = yytext+yyleng; if (x>=0 && x <= yyleng) ptr = x + yytext; else ptr = x; while (lastch > ptr) unput(*--lastch); *lastch = 0; if (ptr >yytext) yyprevious = *--lastch; yyleng = ptr-yytext; } ; while (yylsp-- > yylstate) { unput(yytext[yyleng-1]); yytext[--yyleng] = 0; if (*yylsp != 0 && (yyfnd= (*yylsp)->yystops) && *yyfnd > 0) return(yyracc(*yyfnd++)); } if (yytext[0] == 0) return(0); output(yypreviouextern int yymorfg; yymore() { yymorfg=1; } ch, *ptr; extern int yyleng; int yyprevious; lastch = yytext+yyleng; if (x>=0 && x <= yyleng) ptr = x + yytext; else ptr = x; while (lastch > ptr) unput(*--lastch); *lastch = 0; if (ptr >yytext) yyprevious = *--lastch; yyleng = ptr-yytext; } ; while (yylsp-- > yylstate) { unput(yytext[yyleng-1]); yytext[--yyleng] = 0; if (*yylsp != 0 && (yyfnd= (*yylsp)->yystops) && *yyfnd > 0) return(yyracc(*yyfnd++)); } if (yytext[0] == 0) return(0); output(yypreviouyywrap() { return(1); } e() { yymorfg=1; } ch, *ptr; extern int yyleng; int yyprevious; lastch = yytext+yyleng; if (x>=0 && x <= yyleng) ptr = x + yytext; else ptr = x; while (lastch > ptr) unput(*--lastch); *lastch = 0; if (ptr >yytext) yyprevious = *--lastch; yyleng = ptr-yytext; } ; while (yylsp-- > yylstate) { unput(yytext[yyleng-1]); yytext[--yyleng] = 0; if (*yylsp != 0 && (yyfnd= (*yylsp)->yystops) && *yyfnd > 0) return(yyracc(*yyfnd++)); } if (yytext[0] == 0) return(0); output(yypreviou Program_______ Function________ lgen Main program setflg Interpret arguments defrd Read definitions usrtab Make user-specified character table defst Record user start conditions rdrule Direct input of rules rdcomm Read a rule auto Make automaton for one rule rulen Compute length of rule segment ctrans Interpret escaped characters range Process ranges in character classes start Determine start states for this rule cpyact Copy action header Put out prefix of yylook program tail Put out suffix of yylook program nofree Remove free transitions (empty input) subset Perform subset construction purge Remove unused states anoth Compress by storing only differences of actions common Measure overlap of state actions cform Format table for quick access outstp Make list of rules accepting in states rprint Print an array for Ratfor ssort Shell sort access Accessing most kinds of arrays move Accesses the action table errio Error I-O handling lam Associative memory source chset Character set table csubs Low level string functions extdef External definitions ldefs External declaractions and defines tions cform Format table for quick access outstp Make list of rules ac# include "../lexgen1/ldefs.c" # define NALTS 6 slide(a0,a1,a2) { char *cp; if (a0>NST) error("%d states", NST); switch(a1) { case 0: if (xslide[a0]) return(xslide[a0]); cp=xslide[a0]=calloc(a2,1); while(a2--) *cp++ = 0; return(xslide[a0]); case 1: return(xslide[a0]); case -1: if (xslide[a0]) cfree(xslide[a0],2,1); xslide[a0] = 0; } return(0); } addslide(i,j) { int *p, *q, leng, *tp, temp[NRULES]; if(i==j) return; leng = 2*NALTS*sizeof(i); q= p = slide(i,0,leng); p++; if (*q==0) *q = leng/sizeof(i); while (*p) if (*p++ == j) return; leng = *q; if (p-q >= leng-1) { leng =* 2; tp = temp; while (*tp++ = *q++); slide(i,-1,0); q= p = slide(i, 0, leng*sizeof(p)); tp=temp; while (*p = *tp++) p++; *q = leng; } *p = j; } addmove(i,c,j) { int *p, *q, leng, *tp, temp[NRULES]; int **pp; leng = NALTS*sizeof(i); pp = move(i,c,0,leng); if(*pp == 0) { *pp = j; return; } p = *pp; if (!ptr(p)) { i = p; if(i==j) return; *pp = p = calloc(leng,1); p [0]= NALTS; p[1] = i; p[2] = 0; } q=p; p++; while (*p) if (*p++ == j) return; leng = *q; if (p-q >= leng-1) { leng =* 2; tp = temp; while (*tp++ = *q++); cfree(*pp, leng, 1); q = p = *pp = calloc(leng*sizeof(p), 1); tp=temp; while (*p = *tp++) p++; *q = leng; } *p++ = j; *p = 0; } addstop(i,j) { int *p, *q, v; q= p = stops(i,0); for (; v = *p; p++) if (v == j) return; else if (j > 0 && (v > j || v < 0 )) { *p = j; j= v;} if (p-q >= NALTS-1) error("too many stops state %d",i); else *p = j; } stops(a0,a1) { char *cp; int a2; if (a0>NST) error("%d states", NST); switch(a1) { case 0: if (xstop[a0]) return(xstop[a0]); cp=xstop[a0]=calloc(a2=NALTS*sizeof(a2),1); while(a2--) *cp++ = 0; return(xstop[a0]); case 1: return(xstop[a0]); case -1: if (xstop[a0]) cfree(xstop[a0],10,1); xstop[a0] = 0; } return(0); } ptr(a) { if (a== -1) return (0); if (a<0) return(1); if (a<1024) return(0); return(1); } new( ii, sz) { char *p; if (ii>NST) error("new state overflow"); if (xnew[ii] != 0) return(xnew[ii]); xnew[ii] = p = calloc(sz, 1); while (sz--) *p++ = 0; return(xnew[ii]); } (xstop[a0]) return(xstop[a0]); cp=xstop[a0]=calloc(a2=NALTS*sizeof(a2),1); while(a2--) *cp++ = 0; return(xstop[a0]); case 1: return(xstop[a0]); case -1: if (xstop[a0]) cfree(xstop[a0],10,1); xstop[a0] = 0; } return(0); } ptr(a) { if (a== -1) return (0); if (a<0) return(1); if (a<1024) return(0); return(1); } new( ii, sz) { char *p; if (ii>NST) error("new state overflow"); if (xnew[ii] != 0) return(xne# include "../lexgen1/ldefs.c" # define table(i,c) ((pp=move(i,c,1,0)) ? pp[1] : 0) another() { int act[NCH], *pp, c, i, j, im, m, max, uother[NST], *ntrans; ntrans = uother; for(i=0; i<=nstate; i++) uother[i] = 0; for(i=0; i<=nstate; i++) if (used[i] && (j=other[i])) uother[j] = 1; for(i=0; i<= nstate; i++) { if (used[i]==0 || other[i] != 0 || uother[i] != 0) continue; im = max = 0; for(c=0; cmax && check(act,j)) {max=m; im=j;} } if (im>0) { for(c=0; clast) { t= *--lp; if (ctable[t]==0) chbad(t); addmove(nstate,ctable[t],nstate+1); } prev[level] = nstate; nstate++; break; case '.': /* all chars except \n */ for(c=0; cii = nstate; nstate++; w = njump[level]; for(t=0; tii; addslide(p,nstate); } level--; break; case '|': /* alternation */ jumpfr(level, njump[level]++)->ii = nstate; nstate++; t = prev[level-1]; addslide(t, nstate); break; case '$': /* end of line */ if (*(s+1) == 0) { c = '\n'; extra[m] = 1; addstop(nstate, -m); } goto normal; case '/': /* context sensitivity */ extra[m] = 1; addstop(nstate, -m); addslide(nstate, nstate+1); nstate++; break; } } if (level != 1) warning("unbalanced parentheses"); /* finish up outer level alternations */ w = njump[level]; for(t=0; tii, nstate); return (nstate++); } invert(lbot, ltop) int *lbot, *ltop; { int temp[NCH]; int c; for(c=0;clbot) temp[*--ltop] = 1; for(c=0; c= NCH) /* no actions, only here for stops */ { stoff[ns] = 0; continue; } for(cmax = NCH-1; cmax>=0; cmax--) if (act[cmax]) break; while (verify[omin+NCH]) omin++; startup = omin; do { startup =+ 1; if (startup > crsiz-NCH) error("output table overflow (not your fault, see M. Lesk)"); for (c= cmin; c <= cmax; c++) { if (act[c]==0) continue; if (startup+c < 0) break; else if (verify[startup+c]) break; } } while (c <= cmax); for(c=cmin; c <= cmax; c++) { if (act[c] == 0) continue; verify[startup+c] = ns; advance[startup+c] = act[c]; } stoff[ns] = startup; if (startup> maxst) maxst= startup; } maxst =+ NCH; if (ratfor) { rprint(verify, "verif", maxst); rprint(advance, "advan", maxst); outstp(pstop=xslide, verify); rprint(stoff, "stoff", stnum); rprint(other, "other", stnum); rprint(pstop, "stops", stnum); rprint(extra, "extra", nrule); return; } printf(output, "struct %swork {int *verify, *advance;} %scrank[] {\n", label, label, label); for (i=0; i 0 || i<= 2) printf(output, "%scrank+%d,",label,stoff[i]); else printf(output, "0,"); if (other[i]) printf(output, " %ssvec+%d,", label, other[i]); else printf(output, " 0,"); if (pstop[i]) printf(output, "%svstop+%d,\n",label, pstop[i]); else printf(output, "0,\n"); } printf(output, "0,0,0};\n"); printf(output, "int %sextra[] {\n",label); for(i=0; i040 && c < 0177); # endif # ifdef EBCDIC return(index(c, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,;:><+*)('&%!-=\"")>=0); # endif } 81,182,183,184,185,186,187,188,189, 190,191,192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207,208,209, 210,211,212,213,214,215,216,217,218,219, 220,# include "../lexgen1/ldefs.c" # define table(i,c) ((pp=move(i,c,1,0)) ? pp[1] : 0) common(act, k) int *act; { int c, i, n, *pp; for(n=c=0; c='0' && c <= '9'); } c=='\\' ){ cputc( c , output); c=getchar(); } else if( ctrans(ss) char **ss; { int c, k; if ((c = **ss) != '\\') return(c); switch(c= *++*ss) { case 'n': c = '\n'; break; case 't': c = '\t'; break; case 'r': c = '\r'; break; case 'b': c = '\b'; break; case '\\': c = '\\'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c =- '0'; while ((k = *(*ss+1)) >= '0' && k <= '7') { c = c*8 + k - '0'; (*ss)++; } break; } return(c); } '\\' ){ cputc( c , output); c=getchar(); } else if( # include "../lexgen1/ldefs.c" extern cin, lineno, lgatflg; defrd() { int c, savline; char line[200], *cp; static char lcomm[20]; while(1) { switch(c=getchar()) { case '%': switch(c=getchar()) { case '%': lgate(); gets(line); return; case '+': if (lgatflg) warning("too late to change file name"); gets(label=lcomm); while(space(*label)) label++; continue; case '{': lgate(); savline = lineno; while (gets(line) && !scomp(line,"%}")) printf(output,"%s\n",line); if (line[0] == '%') continue; lineno=savline; error("Non-terminated copy"); case 't': case 'T': /* character table */ usrtab(); continue; case 's': case 'S': defst(); continue; case 'r': case 'R': c = 'r'; case 'c': case 'C': if (lgatflg) warning("too late to specify host language"); ratfor = (c== 'r'); continue; } warning("undefined control line %%%c\n",c); break; case ' ': case '\t': lgate(); while (space(c=getchar())); ungetc(c, cin); cpyact(); cputc('\n',output); while (getchar() != '\n'); break; case '\0': error("unexpected EOF"); case '\n': continue; default: ungetc(c, cin); defclass(); break; } } } int lgatflg 0; lgate() { char fname[20]; if (lgatflg) return; lgatflg=1; printf(-1, fname, "lex.%s.%c", label, ratfor? 'r' : 'c'); output = copen(fname, 'w'); printf( output, "#\n"); if (!ratfor)printf(output,"#"); printf(output, "define YYLMAX 200\n"); /* must go out first*/ } ())); ungetc(c, cin); cpyact(); cputc('\n',output); while (getchar() != '\n'); break; case '\0': error("unexpected EOF"); case '\n': continue; default: ungetc(c, cin); defclass(); break; } } } int lgatflg 0; lgate() { char fname[20]; if (lgatflg) return; lgatflg=1; printf(-1, fname, "lex.%s.%c", label, ratfor? 'r' : 'c'); output = copen(fname, 'w'); printf( output, "#\n"); if (!ratfor)printf(output,"#"); printf(output, "define YYLMAX 200\n"); /* # include "../lexgen1/ldefs.c" int stgate 0; defst() { char sp[100], *s; char tp[20], *t; lgate(); if (stgate++ == 0) printf(output, ratfor ? "define BEGIN yybgin=1+\n" : "# define BEGIN yybgin=yysvec+1+\n"); gets(s=sp); while (*s && index(*s, " \t,") < 0) s++; while (*s) { t = tp; while (*s && index(*s, " \t,") >= 0) s++; while(*s && index(*s, " \t,") < 0) *t++ = *s++; *t=0; if (t>tp) { printf(output, "%s define %s %d\n",ratfor?"":"#", tp, nstate-1); startnam(tp)->ii = nstate; nstate =+ 2; } } } /ldefs.c" int stgate 0; defst() { char sp[100], *s; char tp[20], *t; lgate(); if (stgate++ == 0) printf(output, ratfor ? "define BEGIN yybgin=1+\n" : "# define BEGIN yybgin=yysvec+1+\n"); gets(s=sp); while (*s && index(*s, " \t,") < 0) s++; while (*s) { t = tp; while (*s && index(*s, " \t,") >= 0) s++; while(*s && index(*s, " \t,") < 0) *t++ = *s++; *t=0; if (t>tp) { printf(output, "%s define %s %d\n",ratfor?"":"#", tp, nstate-1); startnam(tp)->ii = nstate; nint lineno 1; gets (s) char *s; { /* gets (s) - read a string with cgetc and store in s */ char *p; extern int cin; p=s; while ((*s = cgetc(cin)) != '\n' && *s != '\0') s++; if (*p == '\0') return (0); *s = '\0'; lineno++; return (p); } getchar() { extern cin; int c; c = cgetc(cin); if (c== '\n') lineno++; return(c); } error(s,p) { printf("%d: ",lineno); printf(s,p); printf("\n"); cexit(); } warning(s,p) { printf("%d: (Warning) ",lineno); printf(s,p); printf("\n"); } nstate; n# include "../lexgen1/ldefs.c" int *xslide[NST]; int *xstop[NST]; int *xnew[NST]; int ngo[NST]; int nstate 3; int nstart 3; int *used xnew; int extra[NRULES]; int other[NST]; int *stoff ngo; char * label "yy"; int ratfor 0; int stnum 0; int output; etchar() { extern cin; int c; c = cgetc(cin); if (c== '\n') lineno++; return(c); } error(s,p) { printf("%d: ",lineno); printf(s,p); printf("\n"); cexit(); } warning(s,p) { printf("%d: (Warning) ",lineno); printf(s,p); printf("\n"); } nstate; n# include "../lexgen1/ldefs.c" head1() { ratfor ? rhd1() : chd1(); } chd1() { printf(output, "extern int yyleng; extern char yytext[];\n"); printf(output, "extern struct {int *yyaa, *yybb, *yycc;} %ssvec[], *yybgin;\n",label); if (scomp(label, "yy")) { printf(output, "int (*yyplex)() &yylexl;\n"); printf(output, "\nyylex() {\n"); printf(output, "return( (*yyplex)() );\n"); printf(output, "}\n"); } printf(output, "# define REJECT {nstr=yyreject(); goto fussy;}\n"); printf(output, "# define ECHO printf(\"%%s\", yytext);\n"); printf(output, "\n\n%slexl() {\n", label); printf(output, "int nstr;\n"); } rhd1() { printf(output, "integer function yylex(dummy)\n"); printf(output, "define YYLMAX 200\n"); printf(output, "define ECHO call yyecho(yytext, yyleng)\n"); printf(output, "define REJECT nstr= yyrjec(yytext, yyleng); goto 30998\n"); printf(output, "integer nstr, yywrap, yylook\n"); printf(output, "integer yyleng, yytext(YYLMAX)\n"); printf(output, "common /yyxel/ yyleng, yytext\n"); printf(output, "common /yyldat/ yyfnd, yymorf, yyprev, yybgin, yylsp, yylsta\n"); printf(output, "integer yyfnd, yymorf, yyprev, yybgin, yylsp, yylsta(YYLMAX)\n"); printf(output, "for(;;)\n"); printf(output, "\t{\n"); printf(output, "\t30999 nstr = yylook(dummy)\n"); printf(output, "\tgo to 30998\n"); printf(output, "\t30000 k = yywrap(dummy)\n"); printf(output, "\t if (k .ne. 0) {\n"); printf(output, "\t\t yylex=0; return;}\n"); printf(output, "\t\t else goto 30999\n"); } head2() { ratfor ? 0 : chd2(); } chd2() { printf(output, "\nwhile((nstr=%slook()) >= 0)\n", label); printf(output, "fussy: switch(nstr)\n {\n"); printf(output, "\n case 0:\n if (yywrap()) return(0); break;\n"); } defclass() { int len, c; char nsp[40], *name, *vsp[100], *val, *tp; for (name=nsp; !space(*name = getchar()); name++); *name++ = 0; while (space(c=getchar())); ungetc(c, cin); gets(val=vsp); tp = definition(nsp, clenf(vsp)+1, 0); while (*tp++ = *val++); } "\t\t else goto 30999\n"); } head2() { ratfor ? 0 : chd2(); } chd2() { printf(# int istate; # define NALTS 4 struct {int kstates[NALTS];} svec; jumpfr(a0,a1) char *a0,*a1; { char keyc[100], *kcp; int keyi[10], *kip; kip=keyi; kcp=keyc; *kip++ = a0; *kip++ = a1; *kcp= 0; return(aabinary(1,keyi, kip-keyi, keyc, sizeof(istate),0)); } definition(a0,a1,a2) char *a0,*a1,*a2; { char keyc[100], *kcp; int keyi[10], *kip; kip=keyi; kcp=keyc; while(*kcp++= *a0++); *kcp= 0; return(aabinary(2,keyi, kip-keyi, keyc, a1,a2)); } startnam(a0) char *a0; { char keyc[100], *kcp; int keyi[10], *kip; kip=keyi; kcp=keyc; while(*kcp++= *a0++); *kcp= 0; return(aabinary(3,keyi, kip-keyi, keyc, sizeof(istate),0)); } struct node {char *aakey, *aadata; struct node *lp, *rp;}; struct node *aaroot[4]; # ifdef unix # define cfree free calloc(m,n) { int storep; storep = alloc(m*n); if (storep == -1) {write(2, "memory space exceeded\n",22); exit();} return(storep); } # endif aaclen(s) char *s; { int aak; for(aak=1; *s++; aak++); return(aak); } aacomp(s, v, l, t) char *s, *t; int *v; { int c,d, *p; p = s; while (l--) if ( (c= *p++) != (d= *v++)) return(c > d ? '>' : '<'); s= p; while ( (c= *s++) == (d= *t++) ) if (c== 0) return('='); return(c>d ? '>' : '<'); } aabinary(ru,vi,li,s,len,ex) char *s; int *vi; { struct node *p, *op, *r, *st, **pp, *gr; char *cp; int *xp; gr = 0; pp = &(aaroot[ru]); while (*pp) { p = *pp; switch(aacomp(p->aakey, vi, li, s)) { case '<': small: pp= &(p->rp); break; case '>': pp= &(p->lp); gr = p; break; case '=': if (ex == 2)  goto small; if (ex >= 0) return(p->aadata); cfree (p->aadata, len, 1); cfree(p->aakey, aaclen(p->aakey)+ li*sizeof(li), 1); if (p->rp == 0) *pp = p->lp; else { r = p->rp; if (r->lp == 0) { r->lp = p->lp; *pp = r; } else { st = r->lp; while (st->lp != 0) { r = st; st = r->lp; } st->lp = p->lp; r->lp = st->rp; st->rp = p->rp; *pp = st; } } cfree (p, sizeof(**aaroot), 1); return(0); } op=p; } /* not there */ if (ex==2) return (gr ? gr->aakey : 0); if (ex != 0) return(0); p = *pp= calloc(1, sizeof(**aaroot)); p->aakey = calloc(aaclen(s)+li*sizeof(li),1); xp = p->aakey; while (li--) *xp++ = *vi++; cp=xp; while (*cp++ = *s++); p->aadata = calloc(len,1); cp = p->aadata; while (len--) *cp++ = 0; p->rp = p->lp = 0; return(p->aadata); } st = r->lp; } st->lp = p->lp; r->lp = st->rp; st->rp = p->rp; *pp = st; } } cfree (p, sizeof(**aaroot), 1); return(0); } op=p; } /* not there# ifdef unix # define CWIDTH 7 # define ASCII 1 # endif # ifdef gcos # define CWIDTH 9 # define ASCII 1 # endif # ifdef ibm # define CWIDTH 8 # define EBCDIC 1 # endif # ifdef ASCII # define NCH 128 # endif # ifdef EBCDIC # define NCH 256 # endif extern int nstate, lineno, stnum, nstart; struct {int ii;}; # define jumpv(a,b) jumpfr(a,b)->ii # define NST 512 # define NRULES 150 extern int *used, ngo[], *xslide[], other[], output, cin; extern int ctable[], *xstop[], *xnew[], extra[]; extern int *stoff; extern char *label; extern int ratfor; ASCII 1 # endif # ifdef gcos # define CWIDTH 9 # define ASCII 1 # endif # ifdef ibm # define CWIDTH 8 # define EBCDIC 1 # endif # ifdef ASCII # define NCH 128 # endif # ifdef EBCDIC # define NCH 256 # endif extern int nstate, lineno, stnum, nstart; struct {int ii;}; # define jumpv(a,b) jumpfr(a,b)->ii # define NST 512 # define NRULES 150 extern int *used, ngo[], *xslide[], other[], output, cin; extern int ctable[], *xstop[], *xnew[], extra[]; extern int *stoff; # include "../lexgen1/ldefs.c" # ifdef unix char *cname "/usr/lex/cform"; char *ratname "/usr/lib/lex/ratform"; # endif # ifdef gcos char *cname "pounce/lookmast"; char *ratname "pounce/ratlook"; # endif # ifdef ibm char *cname "'dot.looklex.text'"; char *ratname "'dot.looklex.fort'"; # endif int debugf; main (argc, argv) char *argv[]; { int ks; char lbuff[200]; setflg(argc,argv); defrd(); head1(); ks = rdrule(); tail(ks); nofree(); subset(); purge(); another(); cform(ks); cin = copen(ratfor ? ratname : cname , 'r'); while (gets(lbuff)) { printf(output, lbuff, label, label, label, label, label); printf(output, "\n"); } cexit(); } r *cname "pounce/lookmast"; char *ratname "pounce/ratlook"; # endif # ifdef ibm char *cname "'dot.looklex.text'"; char *ratname "'dot.looklex.fort'"; # endif int debugf; main (argc, argv) char *argv[]; { int ks; char lbuff[200]; setflg(argc,argv); defrd(); head1(); ks = rdrule(); tail(ks); nofree(); subset(); purge(); another(); cform(ks); cin = copen(ratfor ? ratnam# include "../lexgen1/ldefs.c" # define hsize 3019 # define prime1 3001 # define prime2 3011 struct {int bbkey; char *bbdata;} hashtbl[hsize]; int tsize hsize; int mbuff[2]; move(state,ch,ex,len) { int key, i, p1, p2, q1; char *cp; key = (state<0) { if (ptr(cp= hashtbl[p1].bbdata)) return(cp); mbuff[0] = cp; return(mbuff-1); } else if (ex==0) { return(&hashtbl[p1].bbdata); } else { if (ptr(hashtbl[p1].bbdata)) cfree(hashtbl[p1].bbdata,0,0); hashtbl[p1].bbkey= -1; } p1 = (p1+p2)%hsize; } error("hash table full state %d",state); } 0; return(&hashtbl[p1].bbdata); } else return(0); } else if (hashtbl[p1].bbkey== -1) { if (q1==0) q1=p1; } else if (hashtbl[p1].bbkey == key) if (ex>0) { if (ptr(cp= hashtbl[p1].bbdata)) return(cp); mbuff[0] = cp; return(mbuff-1); } else if (ex==0) { return(&hashtbl[p1].bbdata); } else { if (ptr(hashtbl[p1].bbdata)) cfree(hashtbl[p1].bbdata,0,0); hashtbl[p1].bbkey= -1; } p1 = (p1+p2)%hsize; } error("hash table full state %d",sta# include "../lexgen1/ldefs.c" nofree() { int i,k,l,lt,c, *p, *q; int sbuff[NRULES], *bp, *tp; for(i=1; i<=nstate; i++) { tp = unpack(slide(i,1,0), bp= sbuff); while (bp b) {t=i; i=j; j=t;}; while (a<=b) *lp++ = a++; return(lp); } index(a,s) char *s; { int k; for(k=0; s[k]; k++) if (s[k]== a)  return(k); return(-1); } ifrange(a,b,s,lp) char *s; int *lp; { int i,j,t; if ( ((i=index(a, s))>=0) && ((j=index(b,s))>=0)) { if (i>j) {t=i; i=j; j=t;}; while (i <= j) *lp++ = s[i++]; return(lp); } return(0); } percase, lp)) return(x); if (x= ifrange(a,b, lowercase, lp)) return(x); if (x= ifrange(a,b,digits,lp)) return(x); warning("Non-portable character class"); if (a>b) {t=i; i=j; j=t;}; while (a<=b) *lp++ = a++; return(lp); } index(a,s) char *s; { int k; for(k=0; s[k]; k++) if (s[k]== a) # include "../lexgen1/ldefs.c" # define done {*string=0; return(1);} rdcomm(string, ks) char *string; { int c, stop, rule; char classname[20], *cn, stuff[200], *s, *t; if (gets(stuff) == 0) return(0); rule = !space(stuff[0]); switch (stuff[0]) { case 0: done; case '%': switch (stuff[1]) { case '%': return(0); case '{': printf(output, "%s\n",stuff+2); while (gets(stuff) && !scomp(stuff, "%}")) printf(output, "%s\n", stuff); done; default: warning ("bad % line %s",stuff); return(1); } default: for (s=stuff; c= *s; s++) { if (space(c)) break; switch (*string++ = c) { case '[': case '"': stop = (c == '[' ? ']' : '"'); while ( (*string++ = c = *++s) != stop) if (c == '\\') *string++ = *++s; break; case '\\': *string++ = *++s; break; case '{': for(cn=classname; (*cn= *++s) != '}'; cn++); *cn=0; string--; cn = definition(classname,0,1); if (cn==0) warning("illegal name %s, ignoring",classname); else while(*string = *cn++) string++; break; } } *string = 0; } if (c==0) return(0); if (rule && ks==1) head2(); if (rule) { if (ratfor) printf(output, " \n%d\n", ks+30000); else printf(output, " \ncase %d:\n", ks); } while (space(*s)) s++; if (*s == '|') return(1); for(t=s; *t; t++); ungetc('\n',cin); lineno--; while (t>s) ungetc(*--t, cin); cpyact(); if (rule) printf(output, !ratfor ? "break;" : "next"); gets(stuff); /* absorb last newline */ return(1); } while(*string = *cn++) string++; break; } } *string = 0; } if (c==0) return(0); if (rule && ks==1) head2(); if (rule) { if (ratfor) printf(output, " \n%d\n", ks+30000); else printf(output, " \ncase %d:\n", ks); } while (space(*s)) s++; if (*s == '|') return(1); for(t=s; *t; t++); ungetc('\n',cin); lineno--; while (t>s) ungetc(*--t, cin); cpyact(); if (rule) printf(output, !ratfor ? "break;" : "next"); gets(stuff); /* absorb last new# include "../lexgen1/ldefs.c" rdrule() { int ks, ns; char store[200]; lineno--; for(nstart=ns=nstate; --ns > 1; ) { addslide (ns, ns%2 ? 1 :2); if (ns%2==0) addslide(ns,ns-1); } for (ks=1; ks < NRULES; ks++) { if (!rdcomm(store, ks)) break; if (store[0]==0) {ks--; continue;} ns = makeauto(store, ks); addstop(ns, ks); if (ns>NST) error("too many states"); } lineno++; if (ks <= 1) head2(); return(ks); } if (rule) printf(output, !ratfor ? "break;" : "next"); gets(stuff); /* absorb last new# include "../lexgen1/ldefs.c" rprint(a, s, n) char *s; int *a; { int i; printf(output, "block data\n"); printf(output, "common /L%s/ %s\n", s,s); printf(output, "define S%s %d\n",s,n); printf(output, "integer %s(S%s)\n",s,s); for(i=1;iNST) error("too many states"); } lineno++; if (ks <= 1) head2(); return(ks); } if (rule) printf(output, !ratfor ? "break;" : "next"); gets(stuff); /* absorb last new# include "../lexgen1/ldefs.c" setflg(argc,argv) char *argv[]; { extern int debugf; while (argc > 1 && (argv[1][0] == '-' || argv[1][0]=='+')) { switch (argv[1][0]) { case '+': label=argv[1]+1; break; case '-': switch (argv[1][1]) { case 'd': debugf=1; break; case 'r': case 'R': ratfor=1; break; case 'c': case 'C': ratfor=0; break; } break; } argc--; argv++; } if (argc > 1) cin = copen(argv[1], 'r'); if (cin < 0) error ("can't read input"); } last newsort(nitem, compar, swap) int (*compar)(), (*swap)(); { /* shell sort - copied from kernighan and plauger */ int igap, imax, iplusg, iex, i; for (igap=nitem/2; igap >0; igap =/ 2) { imax = nitem-igap; iex = 1; while (iex) { iex = 0; for(i=0; i 1) cin = copen(argv[1], 'r'); if (cin < 0) error ("can't read input"); } last new# include "../lexgen1/ldefs.c" start(s, fp) char *s; int *fp; { char tp[30], *t; int k, *fi; fi = fp; switch(*s) { case '^': /* beginning of line state 2 */ s++; *fp++ = 2; break; case '<': for(s++; *s && *s != '>'; ) { t = tp; while (index(*s, ",>") < 0) *t++ = *s++; *t = 0; k = startnam(tp)->ii; if (k==0) warning("unknown start condition %s", tp); else *fp++ = k; if (*s==',') s++; } s++; if (*s == '^') /* combination of <> and ^ */ { s++;  while (fi < fp) (*fi++)++; } break; default: /* normal case, start state 1 */ *fp++ = 1; break; } *fp= 0; return(s); } beginning of line state 2 */ s++; *fp++ = 2; break; case '<': for(s++; *s && *s != '>'; ) { t = tp; while (index(*s, ",>") < 0) *t++ = *s++; *t = 0; k = startnam(tp)->ii; if (k==0) warning("unknown start condition %s", tp); else *fp++ = k; if (*s==',') s++; } s++; if (*s == '^') /* combination of <> and ^ */ { s++; # include "../lexgen1/ldefs.c" int stt[30]; struct {int ns; int st[10];}; subset() { int i, c, d, *p, ni, l; int sn, v, w, ons, flag, boundary; int kk, nnew, *np, k2, ki; boundary = nstate; for(i=1; i<=nstate; i++) { for(c=0; c0 && new(nst,2)->ns > 0; nst--) { if (new(nst,2)->ns != n) continue; ps = new(nst,2)->st; pt = stt; pi=n; while(*ps++ == *pt++) if (--pi == 0) return(nst); } new(++nstate, (n+1)*sizeof(n))->ns = n; ps = new(nstate,0)->st; for(pi=0; pil); } exch(i,j) { int t; t=stt[i]; stt[i] = stt[j]; stt[j] = t; } notin(arr, len, i) int *arr; { while (len--) if (*arr++ == i) return(0); return(1); } w(nst,2)->ns != n) continue; ps = new(nst,2)->st; pt = stt; pi=n; while(*ps++ == *pt++) if (--pi == 0) return(nst); } new(++nstate, (n+1)*sizeof(n))->ns = n; ps = new(nstate,0)->st; for(pi=# include "../lexgen1/ldefs.c" tail(ks) { int i, c; if (!ratfor) printf(output,";}\n}\n"); else { printf(output, "\n30998 if (nstr .lt. 0 .or. nstr .gt. %d) goto 30999\n", ks); printf(output, "nstr = nstr+1\n"); printf(output, "goto ("); for(i=0; ist; for(pi=# include "../lexgen1/ldefs.c" usrtab() { char line[100], *s; int i, c, n; gets(s); lineno--; for(i=0; i= NCH) { warning("character value %d out of range",n); continue; } while (space(*s)) s++; while (*s) { c = ctrans(&s); if (ctable[c]) if (printable(c)) error("character '%c' used twice",c); else  error("character %o used twice",c); ctable[c] = n; s++; } } lineno++; } ets(s); lineno--; for(i=0; i= NCH) { warning("character value %d out of range",n); continue; } while (space(*s)) s++; while (*s) { c = ctrans(&s); if (ctable[c]) if (printable(c)) error("character '%c' used twice",c); else #define NSIZE 8 /* size of identifier names */ #define SPSIZE 400 /* size of symbol table */ #define NULL 0 #define FALSE 0 #define TRUE 1 #define ERR 2 /* created non-terminal */ #define EOF 0 /* terminals */ #define DECL 3 #define COMMA 4 #define LPAREN 5 #define RPAREN 6 #define QUOTES 7 #define SCOLON 8 #define LBRAK 9 #define RBRAK 10 #define POP 11 #define OP 12 #define ANDOP 13 #define OROP 14 #define ROP 15 #define STRING 16 #define IDENT 17 #define GOTO 18 #define IF 19 #define ELSE 20 #define DO 21 #define BREAK 22 #define WHILE 23 #define KOND 24 /* created address modes */ #define LABEL 25 #define REG 32 #define RDEC 40 #define RINC 48 #define CON 56 #define MEM 64 #define MIDX 72 /* l.s. 3 bits hold index value */ #define IREG 80 /* indirect-> add 48 */ #define IRDEC 88 #define IRINC 96 #define ICON 104 #define IMEM 112 #define IMIDX 120 /* l.s. 3 bits hold index value */ #define I 48 #define R 7 #define CRSF 128 /* created symbol */ #define SKPF 64 /* skip initiating stack entry */ #define PUBF 32 /* public symbol or used stack entry */ #define DEFF 16 /* defined symbol or immediate stack entry */ #define DCLF 8 /* declared symbol or defining stack entry */ #define BYTF 4 /* byte */ #define RDEF 2 /* redefinable symbol */ #define BCCF 1 /* bad condition code generated */ #define ATTR 4 #define NOP 0 /* operator values */ #define GOESTO 1 #define PLUS 2 #define MINUS 3 #define NOT 4 #define OR 5 #define AND 6 #define ANDNOT 7 #define XOR 8 #define ROTATE 9 #define SHIFT 10 #define GETSNOT 11 #define GETSMI 12 #define TIMES 13 #define DIVIDE 14 #define TEST 15 #define TESTAND 16 #define GETS 17 #define DSHIFT 18 #define SROTATE 19 #define PUSH 20 #define BYTE 21 #define WORD 23 #define GLOBAL 24 #define LOCAL 25 #define SIZE 26 #define CAT 27 #define MEMOP 30 #define REGOP 31 #define SYS 40 #define JSR 41 #define RTS 42 #define GE 4 /* m.s. 8 bits of conditional branch */ #define GT 6 #define NE 2 #define EQ 3 #define LT 5 #define LE 7 #define HI 0202 #define HIS 0206 #define LO 0207 #define LOS 0203 #define N 0201 #define Z 3 #define V 0205 #define C 0207 #define call jsr r5 #define return rts pc #define args 4[r5] #define auto 0[sp] "reg 0(a, b, c, d, e, f)"; "2[sp](arg, arg2)"; "ATSIZE = &(mem 0(byte flags sizeof 1, byte type sizeof 1, value, bias, size, prev))"; "SYMSIZE = &(mem 0(sat sizeof ATSIZE, name sizeof NSIZE))"; "TOKSIZE = &(mem 0(tat sizeof ATSIZE, tbran, fbran, start, sbias, state))"; #define LT 5 #define LE 7 #define HI 0202 #define HIS 0206 #define LO 0207 #defin#define NSIZE 8 /* size of identifier names */ #define NULL 0 #define FALSE 0 #define TRUE 1 #define ERR 2 /* created non-terminal */ #define EOF 0 /* terminals */ #define DECL 3 #define COMMA 4 #define LPAREN 5 #define RPAREN 6 #define QUOTES 7 #define SCOLON 8 #define LBRAK 9 #define RBRAK 10 #define POP 11 #define OP 12 #define ANDOP 13 #define OROP 14 #define ROP 15 #define STRING 16 #define IDENT 17 #define GOTO 18 #define IF 19 #define ELSE 20 #define DO 21 #define BREAK 22 #define WHILE 23 #define KOND 24 /* created address modes */ #define LABEL 25 #define REG 32 #define RDEC 40 #define RINC 48 #define CON 56 #define MEM 64 #define MIDX 72 /* l.s. 3 bits hold index value */ #define IREG 80 /* indirect-> add 48 */ #define IRDEC 88 #define IRINC 96 #define ICON 104 #define IMEM 112 #define IMIDX 120 /* l.s. 3 bits hold index value */ #define I 48 #define R 7 #define CRSF 128 /* created symbol or allocator */ #define SKPF 64 /* skip initiating stack entry */ #define PUBF 32 /* public symbol or used stack entry */ #define DEFF 16 /* defined symbol or immediate stack entry */ #define DCLF 8 /* declared symbol or defining stack entry */ #define BYTF 4 /* byte */ #define BCCF 1 /* bad condition code generated */ #define ATTR 4 #define NOP 0 /* operator values */ #define GOESTO 1 #define PLUS 2 #define MINUS 3 #define NOT 4 #define OR 5 #define AND 6 #define ANDNOT 7 #define XOR 8 #define ROTATE 9 #define SHIFT 10 #define GETSNOT 11 #define GETSMI 12 #define TIMES 13 #define DIVIDE 14 #define TEST 15 #define TESTAND 16 #define GETS 17 #define DSHIFT 18 #define SROTATE 19 #define PUSH 20 #define BYTE 21 #define WORD 23 #define GLOBAL 24 #define LOCAL 25 #define SIZE 26 #define CAT 27 #define MEMOP 30 #define REGOP 31 #define SYS 40 #define JSR 41 #define RTS 42 #define GE 4 /* m.s. 8 bits of conditional branch */ #define GT 6 #define NE 2 #define EQ 3 #define LT 5 #define LE 7 #define HI 0202 #define HIS 0206 #define LO 0207 #define LOS 0203 #define N 0201 #define Z 3 #define V 0205 #define C 0207 struct at {char flags, type; int value, bias, size; struct at *prev; }; struct symbol {struct at sat; char name[NSIZE]; }; struct token {struct at tat; struct symbol *tbran, *fbran; int start, sbias, state; }; struct token e; /* protean stack entry */ struct symbol *dot; /* -> table entry for '.' */ struct symbol *elc; /* -> current elc */ struct symbol *tlist; /* -> pending jump targets */ struct symbol *symtab; /* -> bottom of symbol table */ struct symbol *sptop; /* -> top of table */ struct symbol *spsave; /* -> bottom of local frame */ int spused; /* space used in table */ int space; /* allocated space left */ int atime; /* assembly time nesting depth */ int skip; /* TRUE while skipping */ int debug; /* TRUE for trace printouts */ int line; /* source line number */ int fin; /* selected input file */ int fout; /* selected output file */ int fsyms; /* symbol table file */ int fcode; /* code output file */ bottom of symbol table */ struct symbol *sptop; /* -> top of table */ struct sy%term DECL 3 ',' 4 '(' 5 ')' 6 '"' 7 ';' 8 '[' 9 %term ']' 10 '++' 11 OP 12 '&&' 13 '||' 14 ROP 15 STRING 16 %term IDENT 17 GOTO 18 IF 19 ELSE 20 DO 21 BREAK 22 WHILE 23 %% prog : thing = {et(); } | prog thing = {et(); } thing : ';'; | string ';'; | quotes DECL arglist '"' ';' = {dodecl(v2, v3); endatime(v1, v2); } | exp ';' = {endexp(v1); } | GOTO loc ';' = {dogoto(v1, v2); } | BREAK ';' = {begbreak(v1, NULL); } | BREAK IDENT ';' = {begbreak(v1, v2); } | label prog ')' = {endthen(v1); endlabel(v1); } | '(' prog ')'; | thenpt thing = {endthen(v1); } | elsept thing = {endthen(v1); } | looppt thing = {endloop(v1); endthen(v1); } thenpt : IF test = {begthen(v2); et(); copy(v2); } elsept : thenpt thing ELSE = {begelse(v1); et(); } looppt : WHILE test = {begloop(NULL, v2); et(); copy(v2); } | DO thing WHILE test = {begloop(v1, v4); et(); copy(v4); } exp : loc; | exp OP loc = {binop(v1, v2, v3); } loc : sloc; | loc '++' = {dopop(v1); } | label ')' = {endcall(v1, NULL); } | label arglist ')' = {endcall(v1, v2); } | loc '[' exp ']' = {index(v1, v3); } sloc : IDENT; | quotes exp '"' = {endatime(v1, v2); copy(v2); } | OP STRING = {alloc(v1, v2); copy(v2); } | '[' exp ']' = {indir(v2); copy(v2); } | '(' exp ')' = {set(v2, DCLF, FALSE); copy(v2); } | OP sloc = {unop(v1, v2); copy(v2); } arglist : exp = {doarg(v1, NULL); } | exp ',' arglist = {doarg(v1, v3); } test : '(' kexp ')' = {copy(v2); } kexp : kterm; | kor kterm = {endkbin(v1, v2); } kor : kexp '||' = {begkbin(v1, v2); } kterm : kond; | kand kond = {endkbin(v1, v2); } kand : kterm '&&' = {begkbin(v1, v2); } kond : skond; | ROP = {makond(v1); } | exp ROP loc = {rop(v1, v2, v3); copy(v2); } | exp = {rexp(v1); } skond : quotes kexp '"' = {endatime(v1, v2); copy(v2); } | '(' kexp ')' = {copy(v2); } | OP skond = {knot(v1, v2); copy(v2); } string : STRING = {dostring(v1); } quotes : '"' = {begatime(v1); } label : loc '(' = {dolabel(v1); } | kor kterm = {endkbin/* lc command */ char *tmp0; char *tmp1; char *tmp2; char *tmp4; char ts[1000]; char *tsp ts; char *av[50]; char *clist[50]; char *llist[50]; int instring; int pflag; int cflag; int *ibuf; int *ibuf1; int *ibuf2; int *obuf; char *lp; char *line; int lineno; int exfail; struct symtab { char name[8]; char *value; } *symtab; int symsiz 200; struct symtab *defloc; struct symtab *incloc; char *stringbuf; char *pass0 "/usr/lib/lil1"; char *pass1 "/usr/lib/lil2"; char *pref "/lib/crt0.o"; main(argc, argv) char *argv[]; { char *t; int nc, nl, i, j, c, f20; int dexit(); i = nc = nl = f20 = 0; while(++i < argc) { if(*argv[i] == '-') switch (argv[i][1]) { case 'p': pref = "/lib/mcrt0.o"; continue; case 'P': pflag++; case 'c': cflag++; continue; case '2': if(argv[i][2] == '\0') pref = "/lib/crt2.o"; else pref = "/lib/crt20.o"; f20 = 1; continue; } t = copy(argv[i]); if(getsuf(t)=='l') { clist[nc++] = t; t = setsuf(copy(t), 'o'); } if (nodup(llist, t)) llist[nl++] = t; } if (nc) { if (pflag==0) { tmp0 = copy("/tmp/ctm0a"); while((c=open(tmp0, 0))>=0) { close(c); tmp0[9]++; } while((creat(tmp0, 0666))<0) tmp0[9]++; } signal(2, &dexit); (tmp1 = copy(tmp0))[8] = '1'; (tmp2 = copy(tmp0))[8] = '2'; (tmp4 = copy(tmp0))[8] = '4'; for (i=0; i1) printf("%s:\n", clist[i]); av[0] = "l1"; if (pflag) tmp4 = setsuf(copy(clist[i]), 'r'); av[1] = expand(clist[i]);  if (pflag || exfail) continue; if (av[1] == 0) { cflag++; continue; } av[2] = tmp1; av[3] = tmp2; av[4] = 0; if (callsys(pass0, av)) { cflag++; continue; } av[0] = "l2"; av[1] = tmp1; av[2] = tmp2; av[3] = setsuf(clist[i], 'o'); av[4] = 0; if(callsys(pass1, av)) { cflag++; continue; } cunlink(tmp1); cunlink(tmp2); cunlink(tmp4); } } if (cflag==0 && nl!=0) { i = 0; av[0] = "ld"; av[1] = pref; j = 2; while(ivalue = defloc->name; incloc = lookup("include", 1); incloc->value = incloc->name; stringbuf = sbf; line = ln; lineno = 0; if (fcreat(tmp4, obuf) < 0) { printf("Can't creat %s\n", tmp4); dexit(); } while(getline()) { if (ibuf==ibuf2) putc(001, obuf); /*SOH: insert */ if (ln[0] != '#') for (lp=line; *lp!='\0'; lp++) putc(*lp, obuf); putc('\n', obuf); } fflush(obuf); close(obuf[0]); close(ibuf1[0]); return(tmp4); } getline() { int c, sc, state; struct symtab *np; char *namep, *filname; if (ibuf==ibuf1) lineno++; lp = line; *lp = '\0'; state = 0; if ((c=getch()) == '#') state = 1; while (c!='\n' && c!='\0') { if ('a'<=c && c<='z' || 'A'<=c && c<='Z' || c=='_' || c=='.') { namep = lp; sch(c); while ('a'<=(c=getch()) && c<='z' ||'A'<=c && c<='Z' ||'0'<=c && c<='9' ||c=='_' || c=='.') sch(c); sch('\0'); lp--; np = lookup(namep, state); if (state==1) { if (np==defloc) state = 2; else if (np==incloc) state = 3; else { error("Undefined control"); while (c!='\n' && c!='\0') c = getch(); return(c); } } else if (state==2) { np->value = stringbuf; while ((c=getch())!='\n' && c!='\0') savch(c); savch('\0'); return(1); } continue; } else if ((sc=c)=='\'') { sch(sc); filname = lp; instring++; while ((c=getch())!=sc && c!='\n' && c!='\0') { sch(c); if (c=='\\') sch(getch()); } instring = 0; if (state==3) { *lp = '\0'; while ((c=getch())!='\n' && c!='\0'); if (ibuf==ibuf2) error("Nested 'include'"); if (fopen(filname, ibuf2)<0) error("Missing file %s", filname); else ibuf = ibuf2; return(c); } } sch(c); c = getch(); } sch('\0'); if (state>1) error("Control syntax"); return(c); } error(s, x) { printf("%d: ", lineno); printf(s, x); putchar('\n'); exfail++; cflag++; } sch(c) { if (lp==line+194) error("Line overflow"); *lp++ = c; if (lp>line+195) lp = line+195; } savch(c) { *stringbuf++ = c; } getch() { static peekc; int c; if (peekc) { c = peekc; peekc = 0; return(c); } loop: if ((c=getc1())=='/' && !instring) { if ((peekc=getc1())!='*') return('/'); peekc = 0; for(;;) { c = getc1(); cloop: switch (c) { case '\0': return('\0'); case '*': if ((c=getc1())=='/') goto loop; goto cloop; case '\n': if (ibuf==ibuf1) { putc('\n', obuf); lineno++; } continue; } } } return(c); } getc1() { int c; if ((c = getc(ibuf)) < 0 && ibuf==ibuf2) { close(ibuf2[0]); ibuf = ibuf1; putc('\n', obuf); c = getc1(); } if (c<0) return(0); return(c); } lookup(namep, enterf) char *namep; { char *np, *snp; struct symtab *sp; int i, c; np = namep; i = 0; while (c = *np++) i =+ c; i =% symsiz; sp = &symtab[i]; while (sp->name[0]) { snp = sp; np = namep; while (*snp++ == *np) if (*np++ == '\0' || np==namep+8) { if (!enterf) subst(namep, sp); return(sp); } if (sp++ > &symtab[symsiz]) sp = symtab; } if (enterf) { for (i=0; i<8; i++) if (sp->name[i] = *namep) namep++; while (*namep) namep++; } return(sp); } subst(np, sp) char *np; struct symtab *sp; { char *vp; lp = np; if ((vp = sp->value) == 0) return; sch(' '); while (*vp) sch(*vp++); sch(' '); } getsuf(s) char s[]; { int c; char t, *os; c = 0; os = s; while(t = *s++) if (t=='/') c = 0; else c++; s =- 3; if (c<=14 && c>2 && *s++=='.') return(*s); return(0); } setsuf(s, ch) char s[]; { char *os; os = s; while(*s++); s[-2] = ch; return(os); } callsys(f, v) char f[], *v[]; { int t, status; if ((t=fork())==0) { signal(2, 0); execv(f, v); printf("Can't find %s\n", f); exit(1); } else if (t == -1) { printf("Try again\n"); return(1); } while(t!=wait(&status)); if ((t=(status&0377)) != 0 && t!=14) { if (t!=2) /* interrupt */ printf("Fatal error in %s\n", f); dexit(); } return((status>>8) & 0377); } copy(s) char s[]; { char *otsp; otsp = tsp; while(*tsp++ = *s++); return(otsp); } nodup(l, s) char **l, s[]; { char *t, *os, c; if (getsuf(s) != 'o') return(1); os = s; while(t = *l++) { s = os; while(c = *s++) if (c != *t++) break; if (*t++ == '\0') return(0); } return(1); } cunlink(f) char *f; { if (f==0) return(0); return(unlink(f)); } 377)) != 0 && t!=14) { if (t!=2) /* interrupt */ printf("Fatal error in %s\n", f); dexit(); } return((status>>8) & 0377); } copy(s) char s[]; { char *otsp; otsp = tsp; while(*tsp++ = *s++); return(otsp); } nodup(l, s) char **l, s[]; { char *t, *os, c; if (getsuf(s) != 'o') return(1); os = s; while(t = *l++) { s = os; while(c = *s++) if (c != *t++) break; if (*t++ == '#include "common" int peek -1; /* holds returned lookahead character */ char name[NSIZE]; /* name buffer */ get() {int c; c = (peek < 0) ? getchar() : peek; peek = (c == '\0') ? '\0' : -1; if (c == '\n') line++; return (c); } putback(c) int c; {if ((peek = c) == '\n') --line; } alf(c) int c; {return ('a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '.' || c == '_' ? TRUE : FALSE); } num(c) int c; {return ('0' <= c && c <= '9' ? TRUE : FALSE); } op(c) int c; {int i, j; for (i = 0; j = "=+-<>?*/&~!|^"[i]; i++) if (j == c) return ("=+-<>?*/&!!^^"[i]); return (FALSE); } strend(c) int c; {if (c == '\'') return (TRUE); if (c == '\n' || c == '\0') {putback(c); error("unbalanced '"); return (TRUE); } return (FALSE); } strc(c) int c; {if (c != '\\') return (c); if (strend(c = get())) return ('\''); if (c == '0') return (000); else if (c == 'a') return (006); else if (c == 'e') return (004); else if (c == 'n') return (012); else if (c == 'p') return (033); else if (c == 'r') return (015); else if (c == 't') return (011); else return (c); } char tname[NSIZE + 2]; char *sn(p) char *p; {int i; for (i = 0; i < NSIZE && (tname[i] = *p++); i++) ; tname[i] = '\0'; return (tname); } compare(p1, p2) char *p1, *p2; {int i; i = 0; do if (*p1 != *p2++) return (FALSE); while (*p1++ && ++i < NSIZE); return (TRUE); } struct symbol *lookup(p1, n) struct symbol *p1; char *n; {struct symbol *p; for (p = sptop; p != p1; p = p->prev) if (compare(p->name, n)) return (p); return (FALSE); } struct symbol *add(s, f, t, v, z) char *s; int f, t, v, z; {struct symbol *p; int i; if (--space < 0) {if ((p = sbrk(100 * sizeof *p)) < 0) {error("symbol table full"); exit(TRUE); } if (symtab == NULL) symtab = p; space = 99; } p = &symtab[spused++]; p->prev = sptop; sptop = p; for (i = 0; i < NSIZE && (p->name[i] = s[i]); i++) ; while (i < NSIZE) p->name[i++] = '\0'; p->flags = f; p->type = t; p->value = v; p->bias = test(p, DEFF) ? 0 : p - symtab; p->size = z; return (p); } lex() {int c, cop, escape, i; struct symbol *p; escape = FALSE; e.flags = e.value = e.bias = 0; e.size = 2; e.prev = e.tbran = e.fbran = NULL; while (c = get()) { if (c == ' ' || c == '\t' || c == '\n') continue; if (c == '%') {while ((c = get()) != '\n' && c) ; continue; } if (c == ';') return (SCOLON); if (c == ',') return (COMMA); if (c == '0') {e.flags = DEFF; do e.value = (e.value << 3) + (c - '0'); while (num(c = get())); putback(c); return (CON); } if (c == '\'') {e.flags = DEFF; if (strend(c = get())) return (CON); e.value = strc(c); if (strend(c = get())) return (CON); e.value =| strc(c) << 8; if (strend(c = get())) return (CON); putback(c); return (STRING); } if (c == '[') return (LBRAK); if (c == ']') return (RBRAK); if (c == '(' || c == '{') return (LPAREN); if (c == ')' || c == '}') return (RPAREN); if (c == '"') return (QUOTES); if (c == '\0') return (EOF); if (c == '\\') {escape = !escape; continue; } if (c == 021) {debug = (debug + 1) % 3; continue; } if (c == 001) {--line; continue; } if (cop = op(c)) {i = 0; do if (i < NSIZE) name[i++] = cop; while (cop = op(c = get())); if (i < NSIZE) name[i] = '\0'; putback(c); if (e.value = lookup(NULL, name)) return ((e.value)->type); error("illegal operator %s", sn(name)); setvb(&e, NOP, 0); return (OP); } if (alf(c)) {i = 0; do if (i < NSIZE) name[i++] = c; while (alf(c = get()) || num(c)); if (i < NSIZE) name[i] = '\0'; putback(c); if ((p = lookup(NULL, name)) == NULL) {e.flags =| DCLF; return (MEM); } if (escape && p->type < KOND) {p->type = MEM; p->flags = p->value = p->bias = 0; p->size = 2; } e.flags = p->flags & ATTR; e.value = p; e.size = p->size; return (p->type); } if (num(c)) {e.flags = DEFF; do e.value = (e.value * 10) + (c - '0'); while (num(c = get())); putback(c); return (CON); } error("illegal character %o", c); } } dostring(p1) struct at *p1; {int c, i; gen(i = p1->value, 0); while (strend(c = get()) == FALSE) {i = strc(c); if (strend(c = get())) {gen(i, 0); return (i); } gen(i =| (strc(c) << 8), 0); } return (i); } p->size = 2; } e.flags = p->flags & ATTR; e.value = p; e.size = p->size; return (p->type); } if (num(c)) {e.flags = DEFF; do e.value = (e.value * 10) + (c - '0'); while (num(c = get())); putback(c); return (CON); } error("illegal character %o", c); } } dostring(p1) struct at *p1; {#include 'com' "extern byte (_name sizeof NSIZE)"; % holds lookup name "extern rsave(), rretrn()"; % special functions "extern _sn, _compare, _lookup, _add, _lex, _dostring"; ". = .data"; peek{ -1; % holds returned lookahead character } ". = .text"; get{ if (peek < 0) _getchar(); else a = peek; if (a == '\0') peek = '\0'; else peek = -1; if (a == '\n') _line + 1; } return; putback{ if (arg -> peek == '\n') _line - 1; } return; alf{ arg -> a; if ('a' <= a && a <= 'z' || 'A' <= a && a <= 'Z' || a == '.' || a == '_') a = TRUE; else a = FALSE; } return; num{ if ('0' <= arg && arg <= '9') a = TRUE; else a = FALSE; } return; op{ "\n = byte ='=+-<>?*/&~!|^'"; a = 0; while (n[a] ~= '\0') {if (byte arg == n[a]) {a = byte ='=+-<>?*/&!!^^'[a]; break op; } a + 1; } a = '\0'; } return; strend{ if (arg == '\'') {a = TRUE; break; } if (arg == '\n' || arg == '\0') {putback(arg); _error(='unbalanced \''); a = TRUE; break; } a = FALSE; } return; strc{ if (a = arg ~= '\\') break; if (strend(get() -> arg)) {a = '\''; break; } if (a = arg == '0') a = 000; else if (a == 'a') a = 006; else if (a == 'e') a = 004; else if (a == 'n') a = 012; else if (a == 'p') a = 033; else if (a == 'r') a = 015; else if (a == 't') a = 011; else ; % default is \x = x } return; _sn{ ".data(byte tname sizeof (NSIZE + 2))"; a = arg; b = 0; do tname[b] = byte [a]++; while (b + 1 < NSIZE); tname[b] = '\0'; a = &tname; } return; _compare{ arg -> a = 0; arg2 -> b; do if (byte [a] ~= byte [b]++) {a = FALSE; break _compare; } while (byte [a]++ && arg + 1 < NSIZE); a = TRUE; } return; _lookup{ "args(p1, n)"; call; rsave; 0; e = _sptop; while (e ~= p1) {if (_compare(a = &name + e, n)) {a = e; break _lookup; } e = prev[e]; } a = NULL; } goto rretrn; _add{ "args(s, byte f, byte t, v, z)"; call; rsave; 0; if (_space - 1 < 0) {if (_sbrk("100 * SYMSIZE") < 0) {_error(='symbol table full'); _exit(TRUE); } if (_symtab == NULL) _symtab = a; _space = 99; } b = _spused * SYMSIZE + _symtab -> e; _spused + 1; prev[e] = _sptop; _sptop = e; c = 0; d = &name + e; while (byte [s] ~= '\0' && c < NSIZE) {byte [d]++ = byte [s]; s + 1; c + 1; } while (c < NSIZE) {byte [d]++ = '\0'; c + 1; } flags[e] = f; type[e] = t; value[e] = v; if (flags[e] ?& DEFF) a = 0; else a = e - _symtab * 1 / SYMSIZE; bias[e] = a; size[e] = z; a = e; } goto rretrn; _lex{ call; rsave; &"auto(escape)"; escape = FALSE; e = &_e; 0 -> flags[e] -> value[e] -> bias[e]; 2 -> size[e]; NULL -> prev[e] -> tbran[e] -> fbran[e]; while (true) { if (get() == '%') {while (get() ~= '\n' && a ~= '\0') ; } if (a == ' ' || a == '\t' || a == '\n') continue; if (a == ';') {a = SCOLON; break _lex; } if (a == ',') {a = COMMA; break _lex; } if (a -> c == '0') {flags[e] = DEFF; do value[e] ** 1 ** 1 ** 1 + (c - '0'); while (num(c = get())); putback(c); a = CON; break _lex; } if (c == '\'') {flags[e] = DEFF; if (strend(c = get())) {a = CON; break _lex; } value[e] = strc(c); if (strend(c = get())) {a = CON; break _lex; } value[e] | (strc(c) <*> 8 &~ 0377); if (strend(c = get())) {a = CON; break _lex; } putback(c); a = STRING; break _lex; } if (c == '[') {a = LBRAK; break _lex; } if (c == ']') {a = RBRAK; break _lex; } if (c == '(' || c == '{') {a = LPAREN; break _lex; } if (c == ')' || c == '}') {a = RPAREN; break _lex; } if (c == '"') {a = QUOTES; break _lex; } if (c == '\0') {a = EOF; break _lex; } if (c == '\\') {escape =~ escape; continue; } if (c == 021) {a = _debug + 1 * 1 / 3; b -> _debug; continue; } if (c == 001) {_line - 1; continue; } if (op(c)) {d = 0; do if (d < NSIZE) {_name[d] = a; d + 1; } while (op(c = get())); if (d < NSIZE) _name[d] = '\0'; putback(c); if (_lookup(NULL, &_name)) a -> value[e] = type[a]; else {_error(='illegal operator %s', _sn(&_name)); _setvb(e, NOP, 0); a = OP; } break _lex; } if (alf(c)) {d = 0; do if (d < NSIZE) {_name[d] = c; d + 1; } while (alf(c = get()) || num(c)); if (d < NSIZE) _name[d] = '\0'; putback(c); if (_lookup(NULL, &_name) == NULL) {flags[e] | DCLF; a = MEM; break _lex; } else if (escape && type[a] < KOND) {type[a] = MEM; flags[a] = 0; value[a] = 0; bias[a] = 0; size[a] = 2; } flags[e] = (b = flags[a] & ATTR); value[e] = a; size[e] = size[a]; a = type[a]; break _lex; } if (num(c)) {flags[e] = DEFF; do value[e] = (b = value[e] * 10 + c - '0'); while (num(c = get())); putback(c); a = CON; break _lex; } _error(='illegal character %o', c); } } goto rretrn; _dostring{ "args(p1)"; call; rsave; 0; p1 -> e; _gen(d = value[e], 0); while (strend(c = get()) == FALSE) {d = strc(c); if (strend(c = get())) {_gen(d, 0); a = d; break _dostring; } _gen(d | (strc(c) <*> 8 &~ 0377), 0); } a = d; } goto rretrn; size[e] = size[a]; a = type[a]; break _lex; } if (num(c)) {flags[e] = DEFF; do value[e] = (b = value[e] * 10 + c - '0'); while (num(c = get())); putback(c); a = CON; break _lex; } _error(='illegal character %o', c); } } goto rre#include "common" #define ERROR 0 #define COMPARE 1 #define SHIFT 2 #define REDUCE 3 #define ACCEPT 4 #define STSIZE 40 struct token stack[STSIZE]; /* the parser stack */ int stused; /* space used in stack */ int sthigh; /* high water mark */ struct token *ps; /* ps[1] is leftmost token to reduce */ copy(p) struct at *p; {ps[1].flags = p->flags; ps[1].type = p->type; ps[1].value = p->value; ps[1].bias = p->bias; ps[1].size = p->size; ps[1].prev = p->prev; ps[1].tbran = p->tbran; ps[1].fbran = p->fbran; } int shift; /* TRUE if next token ready */ char next() {if (!shift) {e.type = lex(); shift = TRUE; } if (e.type < KOND) return (e.type); return (IDENT); } char insert[] {-1, SCOLON, COMMA, IDENT, RPAREN, RBRAK, QUOTES, LPAREN, WHILE, EOF, -1}; struct token f; /* error token */ /* int profile[STSIZE]; */ parse() {extern int yygo[], yypgo[], yyr1[], yyr2[], yyact[], yypact[]; extern char name[]; int eflag, n, state, type, *ap, *gp; eflag = 0; shift = FALSE; stused = 0; stack[0].state = 0; ps = &stack[stused]; state = ps[0].state; while (TRUE) {ap = &yyact[yypact[state + 1]]; if (*ap >> 12 == COMPARE) {type = eflag > 0 ? f.type : next(); do if (type != (*ap & 07777)) ap++; while (*++ap >> 12 == COMPARE); } n = *ap & 07777; switch (*ap >> 12) { case ERROR: if ((f.type = insert[++eflag]) >= 0) continue; error("syntax: %s deleted", s(&e)); eflag = -1; shift = FALSE; continue; case SHIFT: ps[1].start = elc->value; ps[1].sbias = elc->bias; state = n; if (eflag) {copy(&f); error("syntax: %s added before %s", s(&f), s(&e)); eflag = -1; } else { if (!skip && test(&e, DCLF)) {e.value = add(name, 0, MEM, 0, 2); e.flags = 0; } if (debug > 1) error("shift %s", s(&e)); copy(&e); eflag = 0; shift = FALSE; } break; case REDUCE: if (debug > 1) error("reduce %d", n); sthigh = stused; stused =- yyr2[n]; ps = &stack[stused]; state = ps[0].state; yyactr(n); for (gp = &yygo[yypgo[yyr1[n]]]; *gp >= 0 && *gp != state; gp =+ 2) ; state = *++gp; break; case ACCEPT: return; } if (stused++ >= STSIZE) {error("stack overflow"); exit(TRUE); } /* profile[stused]++; */ (++ps)[0].state = state; } } main(argc, argv) int argc; char *argv[]; {struct symbol *p, *pt; int bad, better, i, j; extern int errors, hiwater, osize, shorter, longer; if (argc != 4 || (fin = open(argv[1], 0)) < 0 || (fsyms = creat(argv[2], 0666)) < 0 || (fcode = creat(argv[3], 0666)) < 0) {error("bad args"); exit(TRUE); } init(); /* setup symbol table */ add(".abs", DEFF, MEM, 0, 2); /* first 4 entries are elcs */ (elc = add(".text", DEFF, MEM, 0, 2))->bias = 1; add(".data", DEFF, MEM, 0, 2)->bias = 2; add(".bss", DEFF, MEM, 0, 2)->bias = 3; line = 1; /* set starting line no. */ spsave = sptop; /* start new local region */ settoelc(dot); /* set dot to elc */ parse(); /* compile */ endlocal(NULL); /* end new local region */ settoelc(tlist); /* dump pending jump targets */ pipe(-1); /* drain the pipe */ pt = &symtab[spused]; setvb(symtab, spused, 0); do { i = 0; bad = better = FALSE; for (p = symtab; p != pt; p++) {if (p->bias > 3) {if ((j = symtab[i].bias) <= 3) {p->value =+ symtab[j].value; p->bias = symtab[j].bias; better = TRUE; } else if (p->bias != i) bad = TRUE; } i++; } } while (bad && better); if (bad && !better) error("circular definitions"); for (p = symtab; p != pt; p++) {write(fsyms, p->name, 8); i = (test(p, PUBF) ? 040 : 0) | (p->bias <= 3 ? p->bias + 1 : 040); write(fsyms, &i, 2); if (i == 040) write(fsyms, &(p->size), 2); else write(fsyms, &(p->value), 2); } if (debug) {select(1); printf("%d lines, %d table entries\n", line, spused); for (p = symtab; p != pt; p++) printf("%c%c%c%c %s = %o + %o\n", test(p, PUBF) ? 'g' : ' ', test(p, DEFF) ? 'd' : ' ', test(p, DCLF) ? 'l' : ' ', test(p, BYTF) ? 'b' : ' ', sn(p->name), p->value, p->bias); /* printf("stack profile -"); for (i = 0; i < STSIZE; i++) { if (i % 10 == 0) putchar('\n'); printf(" %d", profile[i]); } putchar('\n'); */ printf("%d%s%d%s%d%s%d%s\n", osize, "-word pipe, filled to ", hiwater, " made ", shorter, " shorter, left ", longer, " longer"); flush(); } exit(errors > 0); } #define v0 &ps[0] #define v1 &ps[1] #define v2 &ps[2] #define v3 &ps[3] #define v4 &ps[4] #include "tables" : ' ', test(p, BYTF) ? 'b' : ' ', sn(p->name), p->value, p->bias); /* printf("stack profile -"); for#define BUFSIZE 512 #define BUFEND 256 #define SYMSIZE 12 #define BINSIZE 6 #define EXTERN 040 #define ABSLOAD 0 #define BRANCH 1 #define JUMP 2 #define LOADELC 3 #define CBITS 0666 #define EXEC 0777 #define TRUE 1 #define FALSE 0 struct { char control,opcode; int bval,sn; } binbuf, *binptr; struct csect { int dotsave, *tbuf,*rbuf,offset,tseek,rseek; } csect[2]; struct { char sname[8]; int sflag,svalue; } *symtp , *symtab; outf 0; fin 0; dot 0; dotsect 0; main (argc,argv) int argc; char *argv[]; { char *ofile; int nsymbol,header[8],i,symbytes; int rword,word,x; /* Interpret arguements ... must be * arg1 pathname of symbol table file. * arg2 pathname of intermediate binary file. * arg3 (optional) pathname of output file. */ if (argc<3){ printf ("Input ??: symtab binary\n"); exit(1); } if ((fin=open(argv[1],0))<0){ printf ("Can't open %s\n",argv[1]); exit(1); } symtab=sbrk(4*SYMSIZE); if (read(fin,symtab,4*SYMSIZE)<4*SYMSIZE){ bst: printf ("Bad Symbol table %s\n",argv[1]);  exit(1); } symbytes=(symtab[0].svalue-4)*SYMSIZE; if (symbytes > 0) {sbrk(symbytes); if (read(fin,&symtab[4].sname[0],symbytes)svalue*SYMSIZE; /* Size of symbol table */ header[5]=header[6]=header[7]=0; /* Initialize the control section tables */ csect[0].tseek=16; csect[0].rseek=header[1]+header[2]+16; csect[0].tbuf=sbrk(BUFSIZE); csect[0].rbuf=sbrk(BUFSIZE); csect[0].dotsave=0; csect[0].offset=0; csect[1].tseek=header[1]+16; csect[1].rseek=2*header[1]+header[2]+16; csect[1].tbuf=sbrk(BUFSIZE); csect[1].rbuf=sbrk(BUFSIZE); /* ------When data starts on a segment boundary this will be valid------- csect[1].dotsave=(header[1]+8191)&0160000; ----------------------------------------------------------------- */ csect[1].dotsave=header[1]; csect[1].offset=0; symtab[0].svalue=0; symtab[1].svalue=0; symtab[2].svalue = header[1]; symtab[3].svalue = header[1] + header[2]; for (i = 4; i < nsymbol; i++) if (x = symtab[i].sflag & 7) symtab[i].svalue =+ symtab[x - 1].svalue; if ((fin=open(argv[2],0))<0){ printf ("Can't open object file %s\n",argv[2]); exit(1); } ofile="a.out"; if(argc>=4)ofile=argv[3]; if ((outf=creat(ofile,CBITS))<0){ printf("Can't create %s\n",ofile); exit(1); } /* Initialization complete - begin loading */ x= TRUE; while (read(fin,binptr,BINSIZE)>0){ rword=0; word=binptr->bval; if((i=symtab[binptr->sn].sflag&7)!=0){ rword= (i-1)<<1; word=+ symtab[binptr->sn].svalue; } else if ((symtab[binptr->sn].sflag&EXTERN)!=0){ rword=(binptr->sn<<4)|010; x= FALSE; } switch(binptr->control&3){ case ABSLOAD: if ((binptr->control&4)!=0){ word=- (dot+2); rword=| 1;  } putword(word,rword); break; case BRANCH: word=(binptr->opcode<<8)+ (((word-dot-2)>>1) & 0377); putword(word,0); break; case JUMP: if ((i=binptr->opcode^1)!=0){ putword ((i<<8)+2,0); } putword(0167,0); putword(word-dot-2,rword|1); break; case LOADELC: csect[dotsect].dotsave=dot; dotsect=(rword>>1)-1; dot=csect[dotsect].dotsave; while (dotcontrol, binptr->opcode,binptr->bval,binptr->sn); exit(1); } } if (csect[0].offset!=0)output(0); if(csect[1].offset!=0)output(1); seek(outf,2*(header[1]+header[2])+16,0); write(outf,symtab,nsymbol*SYMSIZE); seek(outf,0,0); write (outf,header,16); close(outf); if (x== TRUE) chmod(ofile,EXEC); close(fin); exit(0); } putword (data,reloc) int data,reloc; { int j; j=csect[dotsect].offset; csect[dotsect].tbuf[j]=data; csect[dotsect].rbuf[j]=reloc; if(++csect[dotsect].offset>=BUFEND)output(dotsect); dot=+2; } output (section) int section; { seek(outf,csect[section].tseek,0); write(outf,csect[section].tbuf,2*csect[section].offset); seek(outf,csect[section].rseek,0); write(outf,csect[section].rbuf,2*csect[section].offset); csect[section].tseek=+ 2*csect[section].offset; csect[section].rseek=+ 2*csect[section].offset; csect[section].offset=0; } oc; { int j; j=csect[dotsect].offset; csect[dotsect].tbuf[j]=data; csect[dotsect].rbuf[j]=reloc; if(++csect[dotsect].offset>=BUFEND)output(dotsect); dot#include "common" #define OSIZE 256 #define GEN 0 #define BRAN 1 #define JUMP 2 #define LOAD 3 #define RFLAG 4 select(f) int f; {if (fout != f) {flush(); fout = f; } } char *mako(i) int i; {int j, k; static char buf[8]; j = k = 0; if (i < 0) {buf[k++] = '1'; i =& 077777; } else for ( ; j < 4; j++) {if ((i >> 12) & 7) break; i =<< 3; } for ( ; j < 5; j++) {buf[k++] = (i >> 12) & 7 | '0'; i =<< 3; } buf[k] = '\0'; return(buf); } puto(i) int i; {printf(" %s", mako(i)); } int wdot 0;  /* working dot for pipe */ int wbias 1; /* working dot bias for pipe */ int welcs[3] {0, 0, 0}; /* working elc's for pipe */ struct {int o, v, b; } out[OSIZE]; /* the output pipe */ int hiwater 0; /* high water mark in pipe */ int nout 0; /* no. of words in pipe */ int osize OSIZE; /* working size of pipe */ int shorter 0; /* no. of jumps made shorter */ int longer 0; /* no. of jumps left longer */ putovb(o, v, b) int o, v, b; {write(fcode, &o, 2); write(fcode, &v, 2); write(fcode, &b, 2); } pipe(o, v, b) int o, v, b; {int drain, i, j, k; extern struct token stack[]; extern int sthigh; extern int stackoff; if (o == -1) drain = TRUE; else { drain = FALSE; out[nout].o = o; out[nout].v = v; out[nout].b = b; if (debug) {puto(o); puto(v); puto(b); putchar('\n'); } nout++; } for (i = 0; i < nout; i++) {o = out[i].o; b = out[i].b; if (b > 2 && test(&symtab[b], DEFF)) {v = symtab[b].value; b = symtab[b].bias; } else v = out[i].v; if ((o & 3) != JUMP) switch (o & 3) { case GEN: case BRAN: putovb(o, out[i].v, out[i].b); wdot =+ 2; break; case LOAD: putovb(o, v, b); welcs[wbias] = wdot; wdot = v; wbias = b; break; } else if (b > 2 && nout < osize && !drain) break; else if (b > 2 || b != wbias || (v - wdot) < -254 || 256 < (v - wdot) || drain) {putovb(o, out[i].v, out[i].b); wdot =+ (o >> 8) == TRUE ? 4 : 6; longer++; } else { putovb(o & ~3 | BRAN, out[i].v, out[i].b); wdot =+ 2; k = (o >> 8) == TRUE ? 2 : 4; if (i + 1 >= nout) elc->value =- k; else { shorter++; for (j = i + 1; j < nout; j++) if (out[j].b == wbias && out[j].v >= wdot) out[j].v =- k; for (j = dot - symtab; j < spused; j++) if (symtab[j].bias == wbias && symtab[j].value >= wdot) symtab[j].value =- k; for (j = 0; j <= sthigh; j++) if (stack[j].sbias == wbias && stack[j].start >= wdot) stack[j].start =- k; } } } if (i) {if (i > hiwater && i < nout) hiwater = i; for (j = i; j < nout; j++) {out[j - i].o = out[j].o; out[j - i].v = out[j].v; out[j - i].b = out[j].b; } nout =- i; } if (drain) {welcs[wbias] = wdot; if (stackoff) error("stack offset %o", stackoff); } } gen(v, b) int v, b; {if (elc->bias != 1 && elc->bias != 2 || elc->value & 1) {error("bad . %o+%o", elc->value, elc->bias); setelc(&symtab[1].value, 1); if (elc->value & 1) elc->value++; } settoelc(tlist); tlist = NULL; elc->value =+ 2; pipe(GEN, v, b); } int errors FALSE; /* TRUE if any errors */ error(f, s1, s2, s3, s4, s5) char *f, *s1, *s2, *s3, *s4, *s5; {errors = TRUE; select(1); printf("%d: ", line); printf(f, s1, s2, s3, s4, s5); putchar('\n'); } char sbuf[128]; /* holds diagnostic strings */ char *sp sbuf; /* -> current 32-byte buffer */ char *sterm[] {"EOF", "??", "error", "DECL", ",", "(", ")", "\"", ";", "[", "]", "++", "OP", "&&", "||", "ROP", "STRING", "IDENT", "GOTO", "IF", "ELSE", "DO", "BREAK", "WHILE", "CONDITION", "LABEL" }; char *pre[] {"reg ", "--[", "[", "&", "mem ", "", "[reg ", "[--[", "[[", "[&", "[mem ", "[" }; char *post[] {"", "]", "]++", "", "", "]", "]", "]]", "]++]", "]", "]", "]]" }; char *scopy(s1, s2) char *s1, *s2; {while (*s1) *s2++ = *s1++; return (s2); } char *s(p1) struct at *p1; {int t; t = p1->type; if (t < REG) return (test(p1, DEFF) || p1->value == NULL ? sterm[t] : sn((p1->value)->name)); t = (t - REG) >> 3; sp = scopy(pre[t], sp); if (!test(p1, DEFF)) sp = scopy(sn((p1->value)->name), sp); else { if (p1->value || !p1->bias) sp = scopy(mako(p1->value), sp); if (p1->value && p1->bias) *sp++ = '+'; if (p1->bias) sp = scopy(sn(symtab[p1->bias].name), sp); } if ((p1->type & ~R) == MIDX || (p1->type & ~R) == IMIDX) {*sp++ = '['; *sp++ = 'r'; *sp++ = (p1->type & R) + '0'; } sp = scopy(post[t], sp); *sp = '\0'; t = sp - sbuf; sp = &sbuf[((t + 32) & ~31) % 128]; return (&sbuf[t & ~31]); } int stackoff 0; /* stack offset during calls */ int nargs; /* no. of arg words in instruction */ int argb[2]; /* offset for stack references */ int argf[2]; /* TRUE if arg is self-relative */ struct at *argp[2]; /* -> stack entry for arg */ doloc(p1) struct at *p1; {struct at *p; int c, r, v; c = p1->type & ~R; r = p1->type & R; v = (p = ref(p1))->value; switch (c) { case REG: break; case IREG: v =+ 010; break; case RINC: v =+ 020; break; case IRINC: v =+ 030; break; case RDEC: v =+ 040; break; case IRDEC: v =+ 050; break; default: argb[nargs] = 0; argf[nargs] = FALSE; argp[nargs] = p; switch (c) { case MIDX: if (test(p, DEFF) && v == 0 && p->bias == 0 && (stackoff == 0 || r != 6)) return (010 + r); v = 060 + r; break; case IMIDX: v = 070 + r; break; case CON: v = 027; break; case ICON: v = 037; break; case MEM: v = 067; argf[nargs] = TRUE; break; case IMEM: v = 077; argf[nargs] = TRUE; break; default: v = -1; } if ((v & 067) == 066) argb[nargs] = stackoff; nargs++; } return (v); } geninst(i, ps, pd) int i; struct at *ps, *pd; {int j; nargs = 0; j = ps ? doloc(ps) << 6 : 0; if (pd) j =| doloc(pd); if (j < 0) error ("illegal operand in %s op %s", s(ps), s(pd)); else { gen(i | j, 0); for (j = 0; j < nargs; j++) { elc->value =+ 2; pipe(GEN + (argf[j] ? RFLAG : 0), argb[j] + argp[j]->value, argp[j]->bias); } } } target(pp1) struct at **pp1; { struct at *linkup(); if (*pp1 == NULL) return; tlist = linkup(tlist, *pp1); *pp1 = NULL; } struct at *fjump(k, p1, p2) int k; struct at *p1, *p2; {char crname[10]; p1 = linkup(p1, p2); if (k == FALSE) return (p1); if (p1 == NULL) {*scopy(mako(spused), scopy("..", crname)) = '\0'; p1 = add(crname, CRSF, MEM, 0, 0); } jump(k, p1->value, p1->bias); return (p1); } struct at *linkup(p1, p2) struct symbol *p1, *p2; {struct symbol *p; if (p1 == NULL) {p1 = p2; p2 = NULL; } if (p2 == NULL) return (p1); if (test(p2, DEFF)) {p = p1; p1 = p2; p2 = p; } if (test(p1, DEFF)) define(p2, 0, MEM, p1->value, p1->bias); else { for (p = p1; p != &symtab[p->bias]; p = &symtab[p->bias]) ; p->bias = p2 - symtab; } return (p1); } jump(k, v, b) int k, v, b; {int i; if (k == FALSE) return; if (tlist && k == TRUE) {if (!test(&symtab[b], DEFF)) linkup(&symtab[b], tlist); else define(tlist, 0, MEM, v, b); } else settoelc(tlist); tlist = NULL; elc->value =+ (k == TRUE) ? 4 : 6; pipe(JUMP | (k << 8), v, b); } setelc(v, b) int v, b; {if (b != elc->bias || v > elc->value) {if (v & 1) v++; settoelc(tlist); tlist = NULL; elc = &symtab[b]; elc->value = v; if (b == 1 || b == 2) pipe(LOAD, v, b); } else if (v < elc->value) error("can't back up . to %o+%o", v, b); } ALSE) return; if (tlist && k == TRUE) {if (!test(&symtab[b], DEFF)) linkup(&symtab[b], tlist); else define(tlist, 0, MEM, v, b); } else settoelc(tlist); tlist = NULL; elc->value =+ (k == TRUE) ? 4 : 6; pipe(JUMP | (k << 8), v, b); } setelc(v, b) int v, b; {if (b != elc->bias || v > elc->value) {if (v & 1) v++; settoelc(tlist); tlist = NULL; elc = &symtab[b]; elc->value = v; if (b == 1 || b == 2) pipe(LOAD,e y.tab.c g/#/d 1;/yyactr/-1d /nterms/-1,$d w tables ck up . to %o+%o", v, b); } ALSE) return; if (tlist && k == TRUE) {if (!test(&symtab[b], DEFF)) linkup(&symtab[b], tlist); else define(tlist, 0, MEM, v, b); } else settoelc(tlist); tlist = NULL; elc->value =+ (k == TRUE) ? 4 : 6; pipe(JUMP | (k << 8), v, b); } setelc(v, b) int v, b; {if (b != elc->bias || v > elc->value) {if (v & 1) v++; settoelc(tlist); tlist = NULL; elc = &symtab[b]; elc->value = v; if (b == 1 || b == 2) pipe(LOAD,#include "common" test(p1, f) struct at *p1; int f; {return ((p1->flags & f) != 0); } set(p1, f1, f2) struct at *p1; int f1, f2; {if (f2) p1->flags =| f1; else p1->flags =& ~f1; } struct at *ref(p1) struct at *p1; {if (test(p1, DEFF)) return (p1); return (p1->value); } struct at *reg(p1) struct at *p1; {if (p1->type == REG) return (ref(p1)); return (NULL); } struct at *con(p1) struct at *p1; {int p; return (p1->type == CON && test(p = ref(p1), DEFF) && p->bias == 0 ? p : NULL); } setvb(p1, v, b) struct at *p1; int v, b; {p1->value = v; p1->bias = b; set(p1, DEFF, TRUE); } define(p1, f, t, v, b) struct symbol *p1; int f, t, v, b; {int bp; do { if (test(p1, DEFF) && p1 != dot) {error("illegal redefinition of %s", sn(p1->name)); return; } if (debug) error("%o+%o = %o+%o %s", p1->value, p1->bias, v, b, sn(p1->name)); bp = p1->bias; p1->flags =| f; p1->type = t; setvb(p1, v, b); if (p1 == dot || p1 == &symtab[bp]) break; p1 = &symtab[bp]; } while (TRUE); } settoelc(p1) struct at *p1; {if (p1) define(p1, 0, MEM, elc->value, elc->bias); } struct symbol *localize(n, f, t, v, z) char n[]; int f, t, v, z; {struct symbol *p; if ((p = lookup(spsave, n)) == NULL) p = add(n, f, t, v, z); else {p->flags =| f; p->size = z; } return (p); } et() {if (dot->bias != elc->bias || dot->value > elc->value) setelc(dot->value, dot->bias); else settoelc(dot); } dopop(p1) struct at *p1; { if (skip) return; if (p1->type == IREG) p1->type = RINC; else error("%s++ illegal", s(p1)); } index(p1, p2) struct at *p1, *p2; {struct at *p, *q; if (skip) return; if ((p = reg(p2)) && !test(p2, ATTR) && (p1->type == CON || p1->type == MEM)) p1->type = MIDX + p->value; else if ((p = con(p2)) && p1->type == MEM) {q = ref(p1); setvb(p1, q->value + p->value * q->size, q->bias); } else error("%s[%s] illegal", s(p1), s(p2)); } indir(p1) struct at *p1; {if (skip) return; if (!test(p1, ATTR)) switch (p1->type & ~R) { case REG: case RDEC: case RINC: case MIDX: case CON: case MEM: p1->type =+ I; return; case IREG: p1->type = IMIDX + (ref(p1)->value & R); setvb(p1, 0, 0); return; } error("[%s] illegal", s(p1)); } begatime(p1) struct at *p1; {if (skip) return; atime =+ 1; setvb(p1, dot->value, dot->bias); } endatime(p1, p2) struct at *p1, *p2; {if (skip) return; atime =- 1; set(p2, PUBF | SKPF, FALSE); } endexp(p1) struct at *p1; {struct at *p; if (skip) return; if (test(p1, PUBF | DCLF)) return; p = ref(p1); if (p1->type == CON || p1->type == MEM) gen(p->value, p->bias); else error("illegal constant %s", s(p1)); } makond(p1) struct at *p1; {setvb(p1, ref(p1)->value, 0); p1->type = KOND; } knot(p1, p2) struct at *p1, *p2; {int p; if (skip) return; if (ref(p1)->value != NOT) error("%s %s illegal", s(p1), s(p2)); else { setvb(p2, ref(p2)->value ^ 1, p2->bias); p = p2->fbran; p2->fbran = p2->tbran; p2->tbran = p; } } alloc(p1, p2) struct at *p1, *p2; {struct at *p; int v; if (skip) return; if (ref(p1)->value != GETS) error("%s STRING illegal", s(p1)); else { p = elc; setelc(symtab[2].value, 2); v = elc->value; if (dostring(p2) & 0177400) gen(0, 0); setelc(p->value, p->bias); p2->type = CON; setvb(p2, v, 2); } } unop(p1, p2) struct at *p1, *p2; {struct at *p, *ps; int op, v; if (skip) return; p = ref(p2); set(p2, DCLF | PUBF, FALSE); switch (op = ref(p1)->value) { case NOP: return; case PUSH: if (p2->type != IREG) break; p2->type = RDEC; return; case GETS: if (con(p2) == NULL || p->bias) break; ps = elc; setelc(symtab[2].value, 2); v = elc->value; gen(p->value, 0); if (p->value & 0177400) gen(0, 0); setelc(ps->value, ps->bias); p2->type = CON; setvb(p2, v, 2); return; case AND: case MEMOP: set(p2, ATTR, FALSE); p2->type = op == AND ? CON : MEM; return; case REGOP: if (!test(p, DEFF) || p->bias || p->value < 0 || 7 < p->value) break; set(p2, ATTR, FALSE); p2->type = REG; return; case WORD: case BYTE: set(p2, ATTR, FALSE); set(p2, BYTF, op == BYTE); return; case MINUS: case NOT: if (con(p2)) setvb(p2, op == MINUS ? -p->value : ~p->value, 0); else if (p2->type == KOND && op == NOT) setvb(p2, p->value ^ 1, p2->bias); else break; return; case SIZE: setvb(p2, p->size, 0); p2->type = CON; return; case RTS: case JSR: if (reg(p2) == NULL) break; p2->type = CON; setvb(p2, op == RTS ? 000200 + p->value : 004037 + (p->value << 6), 0); return; case SYS: if (con(p2) == NULL) break; setvb(p2, 0104400 + p->value, 0); return; } error("%s %s illegal", s(p1), s(p2)); } compat(p1, p2) struct at *p1, *p2; {return ((p1->flags & ATTR) == (p2->flags & ATTR) || (p1->type == REG || p1->type == CON) && !test(p1, BYTF) || (p2->type == REG || p2->type == CON) && !test(p2, BYTF) ?1:0); } byte(p1, p2) struct at *p1, *p2; {return((p1 ? test(p1, BYTF) : FALSE) || (p2 ? test(p2, BYTF) : FALSE) ? 0100000 : 0); } rexp(p1) struct at *p1; {struct at op, pr; if (p1->type == KOND) return; op.flags = DEFF; op.value = NE; pr.type = CON; pr.flags = DEFF; pr.value = pr.bias = 0; rop(p1, &op, &pr); copy(&op); } rop(p1, p2, p3) struct at *p1, *p2, *p3; {struct at *pl, *pr; int op; if (skip) return; pl = ref(p1); op = ref(p2)->value; pr = ref(p3); p2->type = KOND; if (atime) { if (pl->bias != pr->bias) {error("%s %s %s illegal at compile time", s(p1), s(p2), s(p3)); return; } switch (op) { case GE: op = pl->value >= pr->value; break; case GT: op = pl->value > pr->value; break; case NE: op = pl->value != pr->value; break; case EQ: op = pl->value == pr->value; break; case LT: op = pl->value < pr->value; break; case LE: op = pl->value <= pr->value; break; default: error("%s %s %s illegal at compile time", s(p1), s(p2), s(p3)); op = FALSE; } setvb(p2, op, 0); } else { if (!compat(p1, p3)) error("%s %s %s illegal", s(p1), s(p2), s(p3)); else if (con(p3) && pr->value == 0) {if (test(p1, PUBF) && !test(p1, BCCF)) ; else geninst(byte(p1, NULL) + 005700, NULL, p1); } else if (con(p1) && pl->value == 0) {geninst(byte(p3, NULL) + 005700, NULL, p3); if (op != EQ && op != NE) setvb(p2, op ^ 1, 0); } else geninst(byte(p1, p3) + 020000, p1, p3); } } %s illegal at compile time", s(p1), s(p2), s(p3)); op = FALSE; } setvb(p2, op, 0); } else { if (!compat(p1, p3)) error("%s %s %s illegal", s(p1), s(p2), s(p3)); else if (con(p3) && pr->value == 0) {if (test(p1, PUBF) && !test(p1, BCCF)) ; else geninst(byte(p1, NULL) + 005700, NULL, p1); } else if (con(p1) && pl->value == 0) {#include "common" binop(p1, p2, p3) struct at *p1, *p2, *p3; {struct at *pl, *pr, *pt; int k, op; if (skip) return; pl = ref(p1); op = (pt = ref(p2))->value; pr = ref(p3); if (atime || test(pt, CRSF) && !test(p1, PUBF)) /* during atime: DCLF we're defining something PUBF this is what we're defining outside atime: DCLF we've defined something PUBF we've generated machine code */ {switch (op) { case NOP: return; case GETSNOT: case GETSMI: case GETS: set(p1, PUBF | DCLF, TRUE); if (test(p1, DEFF) || op != GETS && pr->bias) break; switch (op) { case GETSNOT: setvb(p3, ~pr->value, 0); break; case GETSMI: setvb(p3, -pr->value, 0); break; case GETS: setvb(p3, pr->value, pr->bias); break; } define(p1->value, p3->flags & ATTR, p3->type, p3->value, p3->bias); return; case GOESTO: set(p1, DCLF, TRUE); if (test(p3, DEFF) || !test(pl, DEFF)) break; define(p3->value, p1->flags & ATTR, p1->type, pl->value, pl->bias); return; case SIZE: set(p1, DCLF, TRUE); if (con(p3) == NULL) break; p1->size = pr->value; return; default: if (!test(p1, PUBF)) {setvb(p1, pl->value, pl->bias); set(p1, DCLF, FALSE); pl = p1; } switch (op) { case PLUS: if (pl->bias && pr->bias) break; pl->value =+ pr->value; pl->bias =+ pr->bias; return; case MINUS: if (pl->bias != pr->bias && pr->bias) break; pl->value =- pr->value; pl->bias =- pr->bias; return; default: if (pl->bias || pr->bias) break; switch (op) { case NOT: pl->value = ~(pl->value ^ pr->value); return; case OR: pl->value =| pr->value; return; case AND: pl->value =& pr->value; return; case ANDNOT: pl->value =& ~pr->value; return; case XOR: pl->value =^ pr->value; return; case SHIFT: pl->value =<< pr->value; return; case TIMES: pl->value =* pr->value; return; case DIVIDE: pl->value =/ pr->value; return; case CAT: pl->value = pl->value & 0377 | (pr->value << 8); p1->type = CON; return; } } }  error("%s %s %s illegal at compile time", s(p1), s(p2), s(p3)); return; } else { set(p1, PUBF, TRUE); set(p1, BCCF, FALSE); switch (op) { case NOP: return; case GOESTO: pt = p1; p1 = p3; p3 = pt; pt = pl; pl = pr; pr = pt; case GETSNOT: case GETSMI: case GETS: if (con(p3) && pr->value == 0 && op != GETSNOT) geninst(byte(p1, NULL) + 005000, NULL, p1); else if(p1->type == KOND && op != GETSMI && p3->type == KOND && ((k = pr->value) == TRUE || k == FALSE)) {k = (k ^ (op == GETSNOT)) << 4; switch (pl->value) { case N: gen(000250 ^ k, 0); return; case Z: gen(000244 ^ k, 0); return; case V: gen(000242 ^ k, 0); return; case C: gen(000241 ^ k, 0); return; } } else if (p3->type == KOND && pr->value == N && op == GETS && !test(p1, BYTF)) geninst(006700, NULL, p1); else if (compat(p1, p3) && (op == GETSNOT || op == GETSMI) && p1->type == p3->type && pl->value == pr->value && pl->bias == pr->bias) geninst(byte(p1, NULL) + (op == GETSNOT ? 005100 : 005400), NULL, p1); else if (compat(p1, p3) && (op == GETS || op == GOESTO)) geninst(byte(p1, p3) + 010000, p3, p1); else break; return; case PLUS: if (con(p3) && pr->value == 1) geninst(byte(p1) + 005200, NULL, p1); else if (p3->type == KOND && pr->value == C) geninst(byte(p1, NULL) + 005500, NULL, p1); else if (!byte(p1, p3)) geninst(060000, p3, p1); else break; return; case MINUS: if (con(p3) && pr->value == 1) geninst(byte(p1) + 005300, NULL, p1); else if (p3->type == KOND && pr->value == C) geninst(byte(p1, NULL) + 005600, NULL, p1); else if (!byte(p1, p3)) geninst(0160000, p3, p1); else break; return; case OR: if (!compat(p1, p3)) break; geninst(byte(p1, p3) + 050000, p3, p1); return; case AND: if (con(p3) == NULL) break; setvb(p3, ~pr->value, 0); case ANDNOT: if (!compat(p1, p3)) break; geninst(byte(p1, p3) + 040000, p3, p1); return; case XOR: if (byte(p1, p3) || p3->type != REG) break; geninst(074000, p3, p1); return; case ROTATE: if (con(p3) == NULL) break; if (pr->value == 1) geninst(byte(p1, NULL) + 006100, NULL, p1); else if (pr->value == -1) geninst(byte(p1, NULL) + 006000, NULL, p1); else break; return; case SROTATE: if (con(p3) == NULL) break; if (pr->value == 8 && !test(p1, BYTF)) {set(p1, BCCF, TRUE); geninst(000300, NULL, p1); } else if (reg(p1) && pl->value & 1 && -16 <= pr->value && pr->value <= 0) geninst(073000 + (pr->value & 077), p1, NULL); else break; return; case SHIFT: if (con(p3) == NULL) break; if (pr->value == 1) geninst(byte(p1, NULL) + 006300, NULL, p1); else if (pr->value == -1) geninst(byte(p1, NULL) + 006200, NULL, p1); else if (reg(p1)) geninst(072000 + (pr->value & 077), p1, NULL); else break; return; case DSHIFT: if (con(p3) == NULL || reg(p1) == NULL) break; geninst(073000 + (pr->value & 077), p1, NULL); return; case TIMES: if (byte(p1, p3) || reg(p1) == NULL) break; geninst(070000, p1, p3); return; case DIVIDE: if (byte(p1, p3) || reg(p1) == NULL) break; geninst(071000, p1, p3); return; case TEST: if (!compat(p1, p3)) break; if (con(p3) && pr->value == 0) geninst(byte(p1, NULL) + 005700, NULL, p1); else geninst(byte(p1, p3) + 020000, p1, p3); return; case TESTAND: if (!compat(p1, p3)) break; geninst(byte(p1, p3) + 030000, p3, p1); return; case JSR: if (byte(p1) || reg(p3) == NULL) break; geninst(004037, p3, p1); return; } error("%s %s %s illegal", s(p1), s(p2), s(p3)); } } byte(p1, p3) || reg(p1) == NULL) break; geninst(071000, p1, p3); return; case TEST: if (!compat(p1, p3)) break; if (con(p3) && pr->value == 0) geninst(byte(p1, NULL) + 005700, NULL, p1); else geninst(byte(p1, p3) + 020000, p1, p3); return; case TESTAND: if (!compat(p1, p3)) break; geninst(byte(p1, p3) + 030000, p3, p1); return; case JSR: if (byte(p1) || reg(p3) == NULL) break; geninst(004037, p#include "common" /* ref(p)->value = truth value of condition p->prev = top of former local region p->tbran, fbran -> created symbols for conditional jump targets p->start, sbias = elc at top of loop */ doarg(p1, p2) struct at *p1, *p2; {extern int stackoff; if (skip) return; if (atime) {if (test(p1, DEFF) || test(p1->value = localize((p1->value)->name, p1->flags & ATTR, MEM, 0, p1->size), DEFF) || (p1->value)->value) {error("illegal declaration %s", s(p1)); p1->value = NULL; } else if (p2) (p1->value)->value = p2->value; } else { if (p2 == NULL && lookup(NULL, ".temp")->value) {geninst(byte(p1, NULL) + 0010016, p1, NULL); setvb(p1, 0, 0); } else { geninst(byte(p1, NULL) + 0010046, p1, NULL); setvb(p1, p2 ? p2->value + 1 : 1, 0); stackoff =+ 2; } } } endcall(p1, p2) struct at *p1, *p2; {extern int stackoff; int v; struct at *p, *q, *r; if (skip) return; if (atime) {set(p1, DCLF, TRUE); if (p2 == NULL) p1->size = 0; else { r = ref(p1);  setvb(p1, r->value, r->bias); v = p1->value; for (p = p2->value; p; p = q) {q = p->value; p->value = 0; define(p, p1->flags & ATTR | DCLF, p1->type, v, p1->bias); if (p1->type == REG || p1->type == IREG) v = (v + p->size / 2) % 8; else v =+ p->size; } p1->size = v - p1->value; p1->value = v; if (1 <= p1->bias && p1->bias <= 3) {v = elc; setelc(p1->value, p1->bias); setelc(v->value, v->bias); } } } else { endlocal(p1->prev); if (p1->type == LABEL) p1->type = p1->bias; geninst(004700, NULL, p1); /* jsr pc,~ */ if (p2) {switch (p2->value) { case 0: break; case 1: gen(005726, 0); break; /* tst (sp)+ */ case 2: gen(022626, 0); break; /* cmp (sp)+,(sp)+ */ default: gen(062706, 0); /* add ~,sp */ gen(2 * p2->value, 0); } stackoff =- 2 * p2->value; } ref(p1)->size = 0; p1->size = 2; set(p1, PUBF | BCCF, TRUE); p1->type = REG; setvb(p1, 0, 0); } } dodecl(p1, p2) struct at *p1, *p2; {struct at *p, *q; if (skip) return; for (p = p2->value; p; p = q) {q = p->value; p->value = 0; if (p1->type == LOCAL) localize(p->name, p1->flags & ATTR | DCLF, MEM, 0, p1->size); else set(p, PUBF, TRUE); } } dolabel(p1) struct at *p1; {if (skip) return; if (!atime) {p1->prev = spsave; spsave = sptop; if (!test(p1, DEFF)) {p1->bias = p1->type; p1->type = LABEL; } } } endlabel(p1) struct at *p1; {if (skip) return; endlocal(p1->prev); if (p1->type == LABEL) {define(p1->value, 0, MEM, p1->start, p1->sbias); (p1->value)->size = elc->value - p1->start; } else error("illegal label %s", s(p1)); p1->type = ERR; } endlocal(ps) struct symbol *ps; {struct symbol *p, *q; p = sptop; sptop = spsave; for ( ; p != spsave; p = q) { q = p->prev; if (!test(p, DEFF)) {if (test(p, DCLF)) error("undefined - %s", sn(p->name)); else {p->prev = sptop; sptop = p; } } if (debug > 1) error("%c%c %s %o+%o", test(p, DEFF) ? 'd' : ' ', test(p, DCLF) ? 'l' : ' ', sn(p->name), p->value, p->bias); } spsave = ps; } begloop(p1, p2) struct at *p1, *p2; {if (skip) return; if (p1) p2->fbran = linkup(p2->fbran, p1->fbran); p2->type = DO; begthen(p2); } begthen(p1) struct at *p1; {int k; if (skip) return; k = ref(p1)->value; if (k == FALSE && p1->tbran == NULL || k == TRUE && p1->fbran == NULL) {endthen(p1); skip = !k; set(p1, SKPF, TRUE); setvb(p1, k, 0); if (debug && skip) error("skipping"); } else switch (next()) { case GOTO: case BREAK: setvb(p1, FALSE, 0); setvb(&e, k, 0); e.tbran = p1->tbran; e.fbran = p1->fbran; p1->tbran = p1->fbran = NULL; break; case SCOLON: break; default: setvb(p1, TRUE, 0); p1->fbran = fjump(k ^ 1, p1->fbran, NULL); target(&(p1->tbran)); } } endthen(p1) struct at *p1; {if (test(p1, SKPF)) {skip = FALSE; if (debug) error("end skip"); } else {target(&(p1->tbran)); target(&(p1->fbran)); } } begelse(p1) struct at *p1; {int k; if (test(p1, SKPF)) {set(p1, SKPF, skip = !skip); if (debug) error(skip ? "skipping" : "end skip"); } else {k = ref(p1)->value; switch (next()) { case GOTO: case BREAK: e.tbran = p1->fbran; e.fbran = p1->tbran; p1->tbran = p1->fbran = NULL; setvb(&e, k ^ 1, e.bias); break; case SCOLON: break; default: p1->tbran = fjump(k, p1->tbran, NULL); target(&(p1->fbran)); } } } endloop(p1) struct at *p1; {if (skip) return; if (p1->tbran) {define(p1->tbran, 0, MEM, p1->start, p1->sbias); p1->tbran = NULL; } jump(ref(p1)->value, p1->start, p1->sbias); p1->type = ERR; } begbreak(p1, p2) struct at *p1, *p2; {extern struct token stack[]; struct token *p; int k; if (skip) return; k = ref(p1)->value; if (p2 == NULL || !test(p2, DEFF)) {for (p = p1; p != stack; --p) if (p2 == NULL && (p->type == DO || p->type == LABEL) || p2 && p->type == LABEL && compare((p->value)->name, (p2->value)->name)) {if (test(p1, BYTF)) {if (p1->tbran) define(p1->tbran, 0, MEM, p->start, p->sbias); jump(k, p->start, p->sbias); } else p->fbran = fjump(k, p->fbran, p1->tbran); p1->tbran = NULL; endthen(p1); return; } } error("illegal break"); } begkbin(p1, p2) struct at *p1, *p2; {int k, op; if (skip) return; k = ref(p1)->value; op = ref(p2)->value; p1->type = ERR; if (atime) { if (k != TRUE && k != FALSE) error("illegal compile-time conditional %s %s", s(p1), s(p2)); else if (k && op == OR || !k && op == AND) set(p1, SKPF, TRUE); } else { if (op == OR) {p1->tbran = fjump(k, p1->tbran, NULL); target(&(p1->fbran)); } else { p1->fbran = fjump(k ^ 1, p1->fbran, NULL); target(&(p1->tbran)); } } } endkbin(p1, p2) struct at *p1, *p2; {if (skip) return; if (!(atime && test(p1, SKPF))) setvb(p1, ref(p2)->value, 0); p1->tbran = linkup(p1->tbran, p2->tbran); p1->fbran = linkup(p1->fbran, p2->fbran); set(p1, SKPF, FALSE); } dogoto(p1, p2) struct at *p1, *p2; {int k; struct at *p; if (skip) return; k = ref(p1)->value; p = ref(p2); if (test(p, DEFF) && p2->type == MEM) fjump(k, p, p1->tbran); else { k = (k ^ 1) << 8; switch (p2->type & ~R) { case MIDX: case IMIDX: case CON: case ICON: case MEM: case IMEM: if (k) gen(k + 2, 0); break; /* br over jmp */ default: if (k) gen(k + 1, 0); break; } settoelc(p1->tbran); geninst(000100, NULL, p2); /* jmp */ } target(&(p1->fbran)); } (p1, SKPF, FALSE); } dogoto(p1, p2) struct at *p1, *p2; {int k; struct at *p; if (skip) return; k = ref(p1)->value; p = ref(p2); if (test(p, DEFF) && p2->type == MEM) fjump(k, p, p1->t#include "common" struct symbol *x(t, v, n) int t, v; char *n; {return (add(n, DEFF, t, v, 2)); } init() { x(OP, RTS, "rts"); x(OP, JSR, "jsr"); x(OP, SYS, "sys"); x(OP, SIZE, "sizeof")->flags =| CRSF; x(OP, CAT, "^^^")->flags =| CRSF; x(OP, REGOP, "reg"); x(OP, MEMOP, "mem"); x(OP, BYTE, "byte"); x(OP, WORD, "word"); x(DECL, GLOBAL, "extern"); x(DECL, LOCAL, "local"); x(KOND, FALSE, "false"); x(KOND, TRUE, "true"); x(KOND, N, "minus"); x(KOND, Z, "zero"); x(KOND, V, "oflow"); x(KOND, C, "carry"); x(OP, DIVIDE, "/"); x(OP, TIMES, "*"); x(OP, TESTAND, "?&"); x(OP, TEST, "?"); x(OP, GETSMI, "=-"); x(OP, GETSNOT, "=!"); x(OP, DSHIFT, "***"); x(OP, SROTATE, "<*>"); x(OP, SHIFT, "**"); x(OP, ROTATE, "<>"); x(OP, XOR, "!!"); x(OP, ANDNOT, "&!"); x(ROP, LOS, "<<="); x(ROP, LO, "<<"); x(ROP, HIS, ">>="); x(ROP, HI, ">>"); x(ROP, LE, "<="); x(ROP, LT, "<"); x(ROP, EQ, "=="); x(ROP, NE, "!="); x(ROP, GT, ">"); x(ROP, GE, ">="); x(OP, AND, "&"); x(OP, OR, "^"); x(ANDOP, AND, "&&"); x(OROP, OR, "^^"); x(CON, FALSE, ".temp"); x(GOTO, TRUE, "goto"); x(IF, 0, "if"); x(ELSE, 0, "else"); x(WHILE, 0, "while"); x(DO, 0, "do"); x(BREAK, TRUE, "break"); x(BREAK, TRUE, "continue")->flags =| BYTF; /* sigh */ x(POP, 0, "++"); x(OP, PUSH, "--"); x(OP, NOT, "!"); x(OP, MINUS, "-"); x(OP, PLUS, "+"); x(OP, GOESTO, "->"); x(OP, GETS, "="); x(REG, 7, "pc"); x(REG, 6, "sp"); x(REG, 5, "r5"); x(REG, 4, "r4"); x(REG, 3, "r3"); x(REG, 2, "r2"); x(REG, 1, "r1"); x(REG, 0, "r0"); sptop = dot = x(MEM, 0, "."); symtab = sptop + 1; spused = 0; } o"); x(IF, 0, "if"); x(ELSE, 0, "else"); x(WHILE, 0, "while"); x(DO, 0, "do"); x(BREAK, TRUE, "break"); x(BREAK, TRUE, "continue")->flags =| BYTF; /* sigh */ x(POP, 0, "++"); x(OP, PUSH, "--"); x(OP, NOT, "!"); x(OP, MINUS, "-"); x(OP, PLUS, "+"); x(OP, GOESTO, "->"); x(OP, GETS, "="); x(REG, 7, "pc"); x(REG, 6, "sp"); x(REG, 5, "r5"); x(REG, 4, "r4"); x(REG, 3, "r3"); x(REG, 2, "r2"); x(REG, 1, "r1"); x(REG, 0, "#include 'com' "x = prev + SYMSIZE"; ". = .data"; "extern _dot, _sptop"; _dot{ ". + 2"; } % -> first entry DEFF ||| MEM; 0; 0; 2; NULL; '.\0\0\0\0\0\0\0'; DEFF ||| OP; RTS; 0; 2; ".-x"; 'rts\0\0\0\0\0'; DEFF ||| OP; JSR; 0; 2; ".-x"; 'jsr\0\0\0\0\0'; DEFF ||| OP; SYS; 0; 2; ".-x"; 'sys\0\0\0\0\0'; "DEFF | CRSF" ||| OP; SIZE; 0; 2; ".-x"; 'sizeof\0\0'; "DEFF | CRSF" ||| OP; CAT; 0; 2; ".-x"; '^^^\0\0\0\0\0'; DEFF ||| OP; REGOP; 0; 2; ".-x"; 'reg\0\0\0\0\0'; DEFF ||| OP; MEMOP; 0; 2; ".-x"; 'mem\0\0\0\0\0'; DEFF ||| OP; BYTE; 0; 2; ".-x"; 'byte\0\0\0\0'; DEFF ||| OP; WORD; 0; 2; ".-x"; 'word\0\0\0\0'; DEFF ||| DECL; GLOBAL; 0; 2; ".-x"; 'extern\0\0'; DEFF ||| DECL; LOCAL; 0; 2; ".-x"; 'local\0\0\0'; DEFF ||| KOND; FALSE; 0; 2; ".-x"; 'false\0\0\0'; DEFF ||| KOND; TRUE; 0; 2; ".-x"; 'true\0\0\0\0'; DEFF ||| KOND; N; 0; 2; ".-x"; 'minus\0\0\0'; DEFF ||| KOND; Z; 0; 2; ".-x"; 'zero\0\0\0\0'; DEFF ||| KOND; V; 0; 2; ".-x"; 'oflow\0\0\0'; DEFF ||| KOND; C; 0; 2; ".-x"; 'carry\0\0\0'; DEFF ||| OP; DIVIDE; 0; 2; ".-x"; '/\0\0\0\0\0\0\0'; DEFF ||| OP; TIMES; 0; 2; ".-x"; '*\0\0\0\0\0\0\0'; DEFF ||| OP; TESTAND; 0; 2; ".-x"; '?&\0\0\0\0\0\0'; DEFF ||| OP; TEST; 0; 2; ".-x"; '?\0\0\0\0\0\0\0'; DEFF ||| OP; GETSMI; 0; 2; ".-x"; '=-\0\0\0\0\0\0'; DEFF ||| OP; GETSNOT; 0; 2; ".-x"; '=!\0\0\0\0\0\0'; DEFF ||| OP; DSHIFT; 0; 2; ".-x"; '***\0\0\0\0\0'; DEFF ||| OP; SROTATE; 0; 2; ".-x"; '<*>\0\0\0\0\0'; DEFF ||| OP; SHIFT; 0; 2; ".-x"; '**\0\0\0\0\0\0'; DEFF ||| OP; ROTATE; 0; 2; ".-x"; '<>\0\0\0\0\0\0'; DEFF ||| OP; XOR; 0; 2; ".-x"; '!!\0\0\0\0\0\0'; DEFF ||| OP; ANDNOT; 0; 2; ".-x"; '&!\0\0\0\0\0\0'; DEFF ||| ROP; LOS; 0; 2; ".-x"; '<<=\0\0\0\0\0'; DEFF ||| ROP; LO; 0; 2; ".-x"; '<<\0\0\0\0\0\0'; DEFF ||| ROP; HIS; 0; 2; ".-x"; '>>=\0\0\0\0\0'; DEFF ||| ROP; HI; 0; 2; ".-x"; '>>\0\0\0\0\0\0'; DEFF ||| ROP; LE; 0; 2; ".-x"; '<=\0\0\0\0\0\0'; DEFF ||| ROP; LT; 0; 2; ".-x"; '<\0\0\0\0\0\0\0'; DEFF ||| ROP; EQ; 0; 2; ".-x"; '==\0\0\0\0\0\0'; DEFF ||| ROP; NE; 0; 2; ".-x"; '!=\0\0\0\0\0\0'; DEFF ||| ROP; GT; 0; 2; ".-x"; '>\0\0\0\0\0\0\0'; DEFF ||| ROP; GE; 0; 2; ".-x"; '>=\0\0\0\0\0\0'; DEFF ||| OP; AND; 0; 2; ".-x"; '&\0\0\0\0\0\0\0'; DEFF ||| OP; OR; 0; 2; ".-x"; '^\0\0\0\0\0\0\0'; DEFF ||| ANDOP; AND; 0; 2; ".-x"; '&&\0\0\0\0\0\0'; DEFF ||| OROP; OR; 0; 2; ".-x"; '^^\0\0\0\0\0\0'; DEFF ||| CON; FALSE; 0; 2; ".-x"; '.temp\0\0\0'; DEFF ||| GOTO; TRUE; 0; 2; ".-x"; 'goto\0\0\0\0'; DEFF ||| IF; 0; 0; 2; ".-x"; 'if\0\0\0\0\0\0'; DEFF ||| ELSE; 0; 0; 2; ".-x"; 'else\0\0\0\0'; DEFF ||| WHILE; 0; 0; 2; ".-x"; 'while\0\0\0'; DEFF ||| DO; 0; 0; 2; ".-x"; 'do\0\0\0\0\0\0'; DEFF ||| BREAK; TRUE; 0; 2; ".-x"; 'break\0\0\0'; "DEFF | BYTF" ||| BREAK; TRUE; 0; 2; ".-x"; 'continue'; DEFF ||| POP; 0; 0; 2; ".-x"; '++\0\0\0\0\0\0'; DEFF ||| OP; PUSH; 0; 2; ".-x"; '--\0\0\0\0\0\0'; DEFF ||| OP; NOT; 0; 2; ".-x"; '!\0\0\0\0\0\0\0'; DEFF ||| OP; MINUS; 0; 2; ".-x"; '-\0\0\0\0\0\0\0'; DEFF ||| OP; PLUS; 0; 2; ".-x"; '+\0\0\0\0\0\0\0'; DEFF ||| OP; GOESTO; 0; 2; ".-x"; '->\0\0\0\0\0\0'; DEFF ||| OP; GETS; 0; 2; ".-x"; '=\0\0\0\0\0\0\0'; DEFF ||| REG; 7; 0; 2; ".-x"; 'pc\0\0\0\0\0\0'; DEFF ||| REG; 6; 0; 2; ".-x"; 'sp\0\0\0\0\0\0'; DEFF ||| REG; 5; 0; 2; ".-x"; 'r5\0\0\0\0\0\0'; DEFF ||| REG; 4; 0; 2; ".-x"; 'r4\0\0\0\0\0\0'; DEFF ||| REG; 3; 0; 2; ".-x"; 'r3\0\0\0\0\0\0'; DEFF ||| REG; 2; 0; 2; ".-x"; 'r2\0\0\0\0\0\0'; DEFF ||| REG; 1; 0; 2; ".-x"; 'r1\0\0\0\0\0\0'; DEFF ||| REG; 0; 0; 2; ".-x"; 'r0\0\0\0\0\0\0'; _sptop{ ". - SYMSIZE"; } % current top of table '->\0\0\0\0\0\0'; DEFF |\{# # int fromflg 0; \} %term CONTIG QTEXT SPACE THIN TAB %term MATRIX LCOL CCOL RCOL COL %term MARK LINEUP %term SUM INT PROD UNION INTER %term LPILE PILE CPILE RPILE ABOVE %term DEFINE TDEFINE NDEFINE DELIM GSIZE GFONT %right FROM TO %left OVER SQRT %right SUP SUB %right SIZE FONT ROMAN ITALIC BOLD FAT %right UP DOWN BACK FWD %left MQ MQ1 %left LEFT RIGHT %right DOT DOTDOT HAT TILDE BAR UNDER VEC DYAD %% stuff : eqn ={ putout($1); } | error ={ error(!FATAL, "syntax error in equation %d", first); }  | ={ eqnreg = 0; } ; eqn : box ={ if(dbg)printf(".\teqn: S%d\n",$1); } | eqn box ={ eqnbox($1,$2); } | eqn MARK ={ mark($1); } | MARK ={ mark(0); } | eqn LINEUP ={ lineup($1); } | LINEUP ={ lineup(0); } ; matrix : MATRIX ={ $$ = ct; } ; collist : column | collist column ; column : lcol MQ list MQ1 ={ column('L',$1,$3); } | ccol MQ list MQ1 ={ column('C',$1,$3); } | rcol MQ list MQ1 ={ column('R',$1,$3); } | col MQ list MQ1 ={ column('-',$1,$3); } ; lcol : LCOL ={ $$ = ct++; } ; ccol : CCOL ={ $$ = ct++; } ; rcol : RCOL ={ $$ = ct++; } ; col : COL ={ $$ = ct++; } ; sbox : sup box %prec SUP ={ $$ = $2; } ; tbox : to box %prec TO ={ $$ = $2; } | %prec FROM ={ $$ = 0; } ; box : box OVER box ={ boverb($1,$3); } | size box %prec SIZE ={ size($1, $2); } | font box %prec FONT ={ font($1, $2); } | FAT box ={ $$ = $2; } | SQRT box ={ sqrt($2); } | lpile MQ list MQ1 ={ lpile('L', $1, ct); ct = $1; } | cpile MQ list MQ1 ={ lpile('C', $1, ct); ct = $1; } | rpile MQ list MQ1 ={ lpile('R', $1, ct); ct = $1; } | pile MQ list MQ1 ={ lpile('-', $1, ct); ct = $1; } | box sub box sbox %prec SUB ={ if(dbg)printf(".\t sub box %d %d %d\n",$1,$3,$4); shift2($1, $3, $4); } | box sub box %prec SUB ={ bshiftb($1, $2, $3); } | box sup box %prec SUP ={ bshiftb($1, $2, $3); } | left eqn right ={ paren($1, $2, $3); } | pbox | box from box tbox %prec FROM ={ fromto($1,$3,$4); fromflg=0; } | box to box %prec TO ={ fromto($1, 0, $3); } | box diacrit ={ diacrit($1,$2); } | fwd box %prec UP ={ move(0,$1,$2); } | up box %prec UP ={ move(1,$1,$2); } | back box %prec UP ={ move(2,$1,$2); } | down box %prec UP ={ move(3,$1,$2); } | matrix MQ collist MQ1 ={ matrix($1,$3); } ; fwd : FWD text ={ $$ = numb($1); } ; up : UP text ={ $$ = numb($1); } ; back : BACK text ={ $$ = numb($1); } ; down : DOWN text ={ $$ = numb($1); } ; diacrit : HAT ={ $$ = 'H'; } | VEC ={ $$ = 'V'; } | DYAD ={ $$ = 'Y'; } | BAR ={ $$ = 'B'; } | UNDER ={ $$ = 'N'; } /* under bar */ | DOT ={ $$ = 'D'; } | TILDE ={ $$ = 'T'; } | DOTDOT ={ $$ = 'U'; } /* umlaut = double dot */ ; from : FROM ; to : TO ; left : LEFT text ={ $$ = $2->c1; } | LEFT MQ ={ $$ = '{'; } ; right : RIGHT text ={ $$ = $2->c1; } | RIGHT MQ1 ={ $$ = '}'; } | ={ $$ = 0; } ; list : eqn ={ lp[ct++] = $1; } | list ABOVE eqn ={ lp[ct++] = $3; } ; lpile : LPILE ={ $$=ct; } ; cpile : CPILE ={ $$=ct; } ; pile : PILE ={ $$=ct; } ; rpile : RPILE ={ $$=ct; } ; size : SIZE text ; font : ROMAN | ITALIC | BOLD | FONT text ; sub : SUB ={ shift(1); } ; sup : SUP ={ shift(-1); } ; pbox : MQ eqn MQ1 ={ $$ = $2; } | QTEXT ={ text('q',$1); } | CONTIG ={ text('c',$1); } | SPACE ={ text('~', $1); } | THIN ={ text('^', $1); } | TAB ={ text('\t', $1); } | SUM ={ funny('S'); } | PROD ={ funny('P'); } | INT ={ funny('I'); } | UNION ={ funny('U'); } | INTER ={ funny('A'); } /* intersection */ ; text : CONTIG | QTEXT | SPACE ={ $$ = & "\\|\\|"; } | THIN ={ $$ = & "\\|"; } ; %% t : ROMAN | ITALIC | BOLD | FONT text ; sub : SUB ={ shift(1# include "ne.h" boverb(p1, p2) int p1, p2; { int h, b, treg; treg = oalloc(); yyval = p1; h = eht[p1] + eht[p2]; b = eht[p2] - VERT(1); if(dbg)printf(".\tb:bob: S%d <- S%d over S%d; b=%d, h=%d\n", yyval, p1, p2, b, h); nrwid(p1, ps, p1); nrwid(p2, ps, p2); printf(".nr %d \\n(%d\n", treg, p1); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2); printf(".ds %d \\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d\\\n", yyval, eht[p2]-ebase[p2]-VERT(1), treg, p2, p2); printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\*(%d\\\n", p2, p1, -eht[p2]+ebase[p2]-ebase[p1], p1); printf("\\h'-\\n(%du-\\n(%du-2u/2u'\\v'%du'\\l'\\n(%du'\\v'%du'\n", treg, p1, ebase[p1], treg, VERT(1)); ebase[yyval] = b; eht[yyval] = h; ofree(p2); ofree(treg); } bshiftb(p1, dir, p2) int p1, dir, p2; { int shval, sh1, sh2, effps, effps2, d1, h1, b1, h2, b2, h; int diffps; yyval = p1; h1 = eht[p1]; b1 = ebase[p1]; h2 = eht[p2]; b2 = ebase[p2]; if( dir > 0 ) { /* subscript */ d1 = VERT(1); shval = - d1 + h2 - b2;  if( d1+b1 > h2 ) /* move little sub down */ shval = b1-b2; ebase[yyval] = b1 + max(0, h2-b1-d1); eht[yyval] = h1 + max(0, h2-b1-d1); } else { /* superscript */ d1 = VERT(1); ebase[yyval] = b1; shval = -VERT(1) - b2; if( VERT(1) + h2 < h1-b1 ) /* raise little super */ shval = -(h1-b1) + h2-b2 - d1; eht[yyval] = h1 + max(0, h2 - VERT(1)); } if(dbg)printf(".\tb:b shift b: S%d <- S%d vert %d S%d vert %d; b=%d, h=%d\n", yyval, p1, shval, p2, -shval, ebase[yyval], eht[yyval]); printf(".as %d \\v'%du'\\*(%d\\v'%du'\n", yyval, shval, p2, -shval); ofree(p2); } eqnbox(p1, p2) int p1, p2; { int b, h; yyval = p1; b = max(ebase[p1], ebase[p2]); eht[yyval] = h = b + max(eht[p1]-ebase[p1], eht[p2]-ebase[p2]); ebase[yyval] = b; if(dbg)printf(".\te:eb: S%d <- S%d S%d; b=%d, h=%d\n", yyval, p1, p2, b, h); printf(".as %d \"\\*(%d\n", yyval, p2); ofree(p2); } size(p1, p2) { yyval = p2; } numb(p1) char *p1; { int i, n, c; for(i=n=0; (c=p1[i++])!='\0'; ) if( c>='0' && c<='9' ) n = n*10 + c-'0'; if(dbg)printf(".\tnumb: %s %d\n", p1, n); return( n ); } font(p1, p2) { yyval = p2; } shift(p1) int p1; { yyval = p1; if(dbg)printf(".\tshift: %d;ps=%d\n", yyval, ps); } sqrt(p2) int p2; { yyval = p2; nrwid(p2, ps, p2); printf(".ds %d \\v'%du'\\e\\L'%du'\\l'\\n(%du'", p2, ebase[p2], -eht[p2], p2); printf("\\v'%du'\\h'-\\n(%du'\\*(%d\n", eht[p2]-ebase[p2], p2, p2); eht[p2] =+ VERT(1); if(dbg)printf(".\tsqrt: S%d <- S%d;b=%d, h=%d\n", p2, p2, ebase[p2], eht[p2]); } lpile(type, p1, p2) int type, p1, p2; { int bi, hi, i, gap, h, b, j, nlist, nlist2, mid; yyval = oalloc(); gap = VERT(1); if( type=='-' ) gap = 0; nlist = p2 - p1; nlist2 = (nlist+1)/2; mid = p1 + nlist2 -1; h = 0; for( i=p1; imid; i-- ) b =+ eht[lp[i]] + gap; ebase[yyval] = (nlist%2) ? b + ebase[lp[mid]] : b - VERT(1) - gap; if(dbg) { printf(".\tS%d <- %c pile of:", yyval, type); for( i=p1; i\\n(%d .nr %d \\n(%d\n", lp[i], yyval, yyval, lp[i]); } printf(".ds %d \\v'%du'\\h'%du*\\n(%du'\\\n", yyval, ebase[yyval], type=='R' ? 1 : 0, yyval); for(i = p2-1; i >=p1; i--) { hi = eht[lp[i]]; bi = ebase[lp[i]]; switch(type) { case 'L': printf("\\v'%du'\\*(%d\\h'-\\n(%du'\\v'0-%du'\\\n", -bi, lp[i], lp[i], hi-bi+gap); continue; case 'R': printf("\\v'%du'\\h'-\\n(%du'\\*(%d\\v'0-%du'\\\n", -bi, lp[i], lp[i], hi-bi+gap); continue; case 'C': case '-': printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d", -bi, yyval, lp[i], lp[i]); printf("\\h'-\\n(%du-\\n(%du/2u'\\v'0-%du'\\\n", yyval, lp[i], hi-bi+gap); continue; } } printf("\\v'%du'\\h'%du*\\n(%du'\n", eht[yyval]-ebase[yyval]+gap, type!='R' ? 1 : 0, yyval); for( i=p1; i h2 ) /* move little sub down */ subsh = b1-b2; supsh = - VERT(1) - b3; d2 = VERT(1); if( VERT(1)+h3 < h1-b1 ) supsh = -(h1-b1) + (h3-b3) - d2; eht[yyval] = h1 + max(0, h3-VERT(1)) + max(0, h2-b1-d1); ebase[yyval] = b1+max(0, h2-b1-d1); nrwid(p2, effps, p2); nrwid(p3, effps, p3); printf(".nr %d \\n(%d\n", treg, p3); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2); printf(".as %d \\v'%du'\\*(%d\\h'-\\n(%du'\\v'%du'\\\n", p1, subsh, p2, p2, -subsh+supsh); printf("\\*(%d\\h'-\\n(%du+\\n(%du'\\v'%du'\n", p3, p3, treg, -supsh); ps =+ 2; ofree(p2); ofree(p3); ofree(treg); } +h3 < h1-b1 ) supsh = -(h1-b1) + (h3-b# include "ne.h" fromto(p1, p2, p3) int p1, p2, p3; { int h, b, h1, b1, pss; yyval = oalloc(); h1 = eht[yyval] = eht[p1]; b1 = ebase[p1]; b = 0; nrwid(p1, ps, p1); printf(".nr %d \\n(%d\n", yyval, p1); if( p2>0 ) { nrwid(p2, pss, p2); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, yyval, yyval, p2); eht[yyval] =+ eht[p2]; b = eht[p2]; } if( p3>0 ) { nrwid(p3, pss, p3); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p3, yyval, yyval, p3); eht[yyval] =+ eht[p3]; } printf(".ds %d ", yyval); /* bottom of middle box */ if( p2>0 ) { printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d", eht[p2]-ebase[p2]+b1, yyval, p2, p2); printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\\n", yyval, p2, -(eht[p2]-ebase[p2]+b1)); } printf("\\h'\\n(%du-\\n(%du/2u'\\*(%d\\h'\\n(%du-\\n(%du+2u/2u'\\\n", yyval, p1, p1, yyval, p1); if( p3>0 ) { printf("\\v'%du'\\h'-\\n(%du-\\n(%du/2u'\\*(%d\\h'\\n(%du-\\n(%du/2u'\\v'%du'\\\n", -(h1-b1+ebase[p3]), yyval, p3, p3, yyval, p3, (h1-b1+ebase[p3])); } printf("\n"); ebase[yyval] = b + b1; if(dbg)printf(".\tfrom to: S%d <- %d f %d t %d; h=%d b=%d\n", yyval, p1, p2, p3, eht[yyval], ebase[yyval]); ofree(p1); if( p2>0 ) ofree(p2); if( p3>0 ) ofree(p3); } paren(leftc, p1, rightc) int p1, leftc, rightc; { int n, m, h1, j, b1, v; h1 = eht[p1]; b1 = ebase[p1]; yyval = p1; n = max(b1+VERT(1), h1-b1-VERT(1)) / VERT(1); if( n<2 ) n=2; m = n-2; if (leftc=='{' ){ n = n%2 ? n : ++n; if( n<3 ) n=3; m = n - 3; } eht[yyval] = VERT(2 * n); ebase[yyval] = (n)/2 * VERT(2); if (n%2 == 0) ebase[yyval] =- VERT(1); printf(".ds %d \\v'%du'", yyval, v); switch( leftc ) { case 'n': /* nothing */ case '\0': break; case 'f': /* floor */ brack(m, "\\(bv", "\\(bv", "\\(lf"); break; case 'c': /* ceiling */ brack(m, "\\(lc", "\\(bv", "\\(bv"); break; case '{': printf("\\b'\\(lt"); for(j = 0; j < m; j =+ 2) printf("\\(bv"); printf("\\(lk"); for(j = 0; j < m; j =+ 2) printf("\\(bv"); printf("\\(lb'"); break; case '(': brack(m, "\\(lt", "\\(bv", "\\(lb"); break; case '[': brack(m, "\\(lc", "\\(bv", "\\(lf"); break; default: brack(m, &leftc, &leftc, &leftc); break; } printf("\\v'%du'\\*(%d", -v, p1); if( rightc ) { printf("\\v'%du'", v); switch( rightc ) { case 'f': /* floor */ brack(m, "\\(bv", "\\(bv", "\\(rf"); break; case 'c': /* ceiling */ brack(m, "\\(rc", "\\(bv", "\\(bv"); break; case '}': printf("\\b'\\(rt"); for(j = 0; j< m; j =+ 2)printf("\\(bv"); printf("\\(rk"); for(j = 0; j< m; j =+ 2) printf("\\(bv"); printf("\\(rb'"); break; case ']': brack(m, "\\(rc", "\\(bv", "\\(rf"); break; case ')': brack(m, "\\(rt", "\\(bv", "\\(rb"); break; default: brack(m, &rightc, &rightc, &rightc); break; } printf("\\v'%du'", -v); } printf("\n"); if(dbg)printf(".\tcurly: h=%d b=%d n=%d v=%d l=%c, r=%c\n", eht[yyval], ebase[yyval], n, v, leftc, rightc); } brack(m, t, c, b) int m; char *t, *c, *b; { int j; printf("\\b'%s", t); for( j=0; j=", "\\(>=", "<=", "\\(<=", "==", "\\(==", "!=", "\\(!=", "+-", "\\(+-", "->", "\\(->", "<-", "\\(<-", "<<", "<\\h'-.3m'<", ">>", ">\\h'-.3m'>", "inf", "\\(if", "infinity", "\\(if", "partial", "\\(pd", "half", "\\fR\\(12\\fP", "prime", "\\(fm", "approx", "~\b\\d~\\u", "nothing", "", "cdot", "\\v'-.5'.\\v'.5'", "times", "\\|\\(mu\\|", "del", "\\(gr", "grad", "\\(gr", "...", "\\v'-.3m'\\|\\|.\\|\\|.\\|\\|.\\|\\|\\v'.3m'", ",...,", ",\\|\\|.\\|\\|.\\|\\|.\\|\\|,\\|", "alpha", "\\(*a", "beta", "\\(*b", "gamma", "\\(*g", "GAMMA", "\\(*G", "delta", "\\(*d", "DELTA", "\\(*D", "epsilon", "\\(*e", "omega", "\\(*w", "OMEGA", "\\(*W", "lambda", "\\(*l", "LAMBDA", "\\(*L", "mu", "\\(*m", "nu", "\\(*n", "theta", "\\(*h", "THETA", "\\(*H", "phi", "\\(*f", "PHI", "\\(*F", "pi", "\\(*p", "PI", "\\(*P", "sigma", "\\(*s", "SIGMA", "\\(*S", "xi", "\\(*c", "XI", "\\(*C", "zeta", "\\(*z", "iota", "\\(*i", "eta", "\\(*y", "kappa", "\\(*k", "rho", "\\(*r", "tau", "\\(*t", "omicron", "\\(*o", "upsilon", "\\(*u", "UPSILON", "\\(*U", "psi", "\\(*q", "PSI", "\\(*Q", "chi", "\\(*x", "and", "\\fRand\\fP", "for", "\\fRfor\\fP", "if", "\\fRif\\fP", "Re", "\\fRRe\\fP", "Im", "\\fRIm\\fP", "sin", "\\fRsin\\fP", "cos", "\\fRcos\\fP", "tan", "\\fRtan\\fP", "arc", "\\fRarc\\fP", "sinh", "\\fRsinh\\fP", "coth", "\\fRcoth\\fP", "tanh", "\\fRtanh\\fP", "cosh", "\\fRcosh\\fP", "lim", "\\fRlim\\fP", "log", "\\fRlog\\fP", "max", "\\fRmax\\fP", "min", "\\fRmin\\fP", "ln", "\\fRln\\fP", "exp", "\\fRexp\\fP", "det", "\\fRdet\\fP", 0, 0 }; int csp; int psp; #define CSSIZE 400 char cs[420]; text(t,p1) int t; char *p1; { int i,j,c; yyval = oalloc(); ebase[yyval] = 0; eht[yyval] = VERT(2); if( t=='q' ) j = p1; else if ( t == '~' ) j = &"\\ "; else if ( t == '^' ) j = &""; else if ( t == '\t' ) j = &"\\t"; else if( (i=lookup(p1,restab))>=0 ) j = restab[i].resval; else { for( csp=psp=0; (c=p1[psp++])!='\0'; ){ trans(c,p1); if( csp>CSSIZE ){ p1[25] = '\0'; error(FATAL,"converted token %s... too long",p1); } } cs[csp] = '\0'; j = cs; } if(dbg)printf(".\t%ctext: S%d <- %s; b=%d,h=%d\n", t, yyval, j, ebase[yyval], eht[yyval]); printf(".ds %d \"%s\n", yyval, j); } trans(c,p1) int c; char *p1; { switch( c){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '!': roman(c); break; case '(': case '[': case ')': case ']': shim(); roman(c); break; case '+': case '|': shim(); roman(c); shim(); break; case '=': case '>': case '<': if( p1[psp]=='=' ){ /* look ahead for == <= >= */ name4(c,'='); psp++; } else { shim(); cs[csp++] = c; shim(); } break; case '-': if( p1[psp]=='>' ){ shim(); name4('-','>'); psp++; } else { shim(); name4('m','i'); shim(); } break; case '/': name4('s','l'); break; case '~': case ' ': shim(); shim(); break; case '^': shim(); break; case '\\': /* troff - pass 2 or 3 more chars */ cs[csp++] = c; cs[csp++] = c = p1[psp++]; cs[csp++] = p1[psp++]; if( c=='(' ) cs[csp++] = p1[psp++]; if( c=='*' && cs[csp-1] == '(' ){ cs[csp++] = p1[psp++]; cs[csp++] = p1[psp++]; } break; case '\'': name4('f','m'); break; default: cs[csp++] = c; break; } } shim() { ; } roman(c) int c; { cs[csp++] = c; } name4(c1,c2) int c1,c2; { cs[csp++] = '\\'; cs[csp++] = '('; cs[csp++] = c1; cs[csp++] = c2; } case '^': shim(); brea#include "ne.h" #define SIGPIPE 13 /* troff has stopped reading */ int gsize 10; int gfont 'R'; char in[600]; /* input buffer */ int exit(); int noeqn; main(argc,argv) int argc; char *argv[];{ int i, type; first = 0; lefteq = righteq = '\0'; signal(SIGPIPE, &exit); setfile(argc,argv); while( (type=getline(in)) != '\0' ){ eqline = linect; if( in[0]=='.' && in[1]=='E' && in[2]=='Q' ){ for( i=11; i<100; used[i++]=0 ); printf("%s",in); printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); init();  yyparse(); if( eqnreg>0 ){ printf("'nr %d \\w'\\*(%d'\n", eqnreg, eqnreg); printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht); printf(".rn %d 10\n", eqnreg); if(!noeqn)printf("\\*(10\n"); } printf(".ps \\n(99\n.ft \\n(98\n"); printf(".EN"); if( lastchar == '\0' ){ putchar('\n'); break; } if( putchar(lastchar) != '\n' ) while( putchar(getc()) != '\n' ); flush(); } else if( type == lefteq ) inline(); else printf("%s",in); } flush(); exit(0); } getline(s) char *s; { char c; while((*s++=c=getc())!='\n' && c!='\0' && c!=lefteq ); if( c==lefteq ) s--; *s++ = '\0'; return(c); } inline() { int i,j,ds,t; printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); ds = oalloc(); printf(".ds %d \"\n", ds); do{ printf(".as %d \"%s\n", ds, in); init(); yyparse(); if( eqnreg > 0 ) { printf(".as %d \\*(%d\n", ds, eqnreg); ofree(eqnreg); } printf(".ps \\n(99\n.ft \\n(98\n"); } while( (t=getline(in)) == lefteq ); printf(".as %d \"%s", ds, in); printf(".ps \\n(99\n.ft \\n(98\n"); printf("\\*(%d\n", ds); ofree(ds); flush(); } putout(p1) int p1; { extern int gsize, gfont; int before, after; eqnht = eht[p1]; printf(".ds %d \\x'0'", p1); before = eht[p1] - ebase[p1] - VERT(3); /* 3 = 1.5 lines */ if( before > 0 ) printf("\\x'0-%du'", before); printf("\\f%c\\s%d\\*(%d\\s\\n(99\\f\\n(98",gfont,gsize,p1); after = ebase[p1] - VERT(1); if( after > 0 ) printf("\\x'%du'", after); putchar('\n'); eqnreg = p1; if(dbg)printf(".\tanswer <- S%d: h=%d, b=%d, before=%d, after=%d\n", p1, eht[p1], ebase[p1], before, after); } max(i,j) int i,j; { return( i>j ? i : j ); } oalloc(){ int i; for( i=11; i<100; i++) if( used[i]++ == 0 ) return(i); error( FATAL, "no strings left", i); } ofree(n) int n; { used[n] = 0; } setps(p) int p; { printf(".ps %d\n", p); } nrwid(n1, p, n2) int n1, p, n2; { printf(".nr %d \\w'\\*(%d'\n", n1, n2); } setfile(argc, argv) int argc; char *argv[]; { svargc = --argc; svargv = argv; while( svargc > 0 && svargv[1][0] == '-'){ switch( svargv[1][1] ){ case 'd': lefteq=svargv[1][2]; righteq=svargv[1][3]; break; case 's': gsize = numb(&svargv[1][2]); break; case 'f': gfont = svargv[1][2]; break; case 'e': noeqn++; break; default: dbg = 1; } svargc--; svargv++; } ptr = 0; fout = dup(1); ifile = 1; linect = 1; if( svargc <= 0 ) fin = dup(0); else if( (fin = open(svargv[1], 0)) < 0) error( FATAL,"can't open file %s", svargv[1]); } yyerror(){;} init(){ ct = 0; ps = gsize; ft = gfont; first++; } error(fatal, s1, s2) int fatal; char *s1, *s2; { int sfout; if( fatal>0 ) printf("fatal error: "); printf(s1,s2); printf(" file %s, between lines %d and %d\n", svargv[ifile], eqline, linect); flush(fout); sfout = fout; fout = 2; if( fatal>0 ) printf("fatal error: "); printf(s1,s2); printf(" file %s, between lines %d and %d\n", svargv[ifile], eqline, linect); flush(2); fout = sfout; if( fatal > 0 ) exit(1); } ; } yyerror(){;} init(){ ct = 0; ps = gsize; ft = gfont; f#include "ne.h" mark(n) int n; { if( n ) printf(".as %d \\k(97\n", n); else { yyval = oalloc(); printf(".ds %d \\k(97\n", yyval); nrwid(yyval, ps, yyval); eht[yyval] = eht[n]; ebase[yyval] = ebase[n]; } if(dbg)printf(".\tmark %d as %d\n", n, yyval); } lineup(n) int n; { if( n ) { nrwid(n, ps, n); printf(".ds %d \\h'|\\n(97u-\\n(%du'\\*(%d\n", n, n, n); } else { yyval = oalloc(); printf(".ds %d \\h'|\\n(97u'\n", yyval); nrwid(yyval, ps, yyval); eht[yyval] = eht[n]; ebase[yyval] = ebase[n]; } if(dbg)printf(".\tlineup %d in %d\n", n, yyval); } n); else { yyval = oalloc(); printf(".ds %d \\k(97\n", yyval); nrwid(yyval, ps, yyval); eht[yyval] = eht[n]; ebase[yyval] = ebase[n]; } if(dbg)printf(".\tmark %d as %d\n", n, yyval); } lineup(n) int n; { if( n ) { nrwid(n, ps, n); printf(".ds %d \\h'|\\n(97u-\\n(%du'\\*(%d\n", n, n, n); } else { yyval = oalloc(); printf(".ds %d \\h'|\\n(97u'\n", yyval); nrwid(yyval, ps, yyval); eht[yyval] = eht[n]; ebase[yyv#include "ne.h" column(type, p1, p2) int type, p1, p2; { int i, n; lp[p1] = ct - p1 - 1; if( dbg ){ printf(".\t%c column of", type); for( i=p1+1; i= 0){ lastchar = (peek<0) ? *swt[sw]++ : peek; peek = -1; if(lastchar != '\0')return(lastchar); peek = speek[sw--]; return(' '); } lastchar = (peek<0) ? getchar() : peek; if( lastchar=='\n' ) linect++; peek = -1; if( lastchar!= '\0' ) return(lastchar); if( ++ifile > svargc ){ peek = '\0'; return('\0'); } close(fin); linect = 1; if( (fin=open(svargv[ifile],0)) >= 0 ) goto loop; error(FATAL,"can't open file %s\n", svargv[ifile]); } yylex(){ int c, type; beg: while( (c=getc())==' ' || c=='\n'); yylval=c; switch(c){ case '\0': return('\0'); case '~': return(SPACE); case '^': return(THIN); case '\t': return(TAB); case '{': return(MQ); case '}': return(MQ1); case '"': for(sp=0; (c=getc())!='"'; ){ if(c !='\\')token[sp++]=c; else { if((c=getc())!= '"')token[sp++]='\\'; token[sp++] = c; } if( sp>=SSIZE ) error(FATAL,"quoted string %.20s... too long", token); } token[sp]='\0'; yylval= &token[0]; return(QTEXT); } if( c==righteq ) return('\0'); getstr(token, c); if((type = lookup(token,deftab)) >= 0){ if(sw >= 9) error(FATAL,"definitions nested > 9", sw); swt[++sw] = deftab[type].sptr; speek[sw] = peek; peek = -1; goto beg; } type = lookup(token,keytab); if( type < 0 ) return(CONTIG); if( keytab[type].keyval==DEFINE || keytab[type].keyval==TDEFINE ) { define(keytab[type].keyval); goto beg; } else if( keytab[type].keyval==DELIM ) { delim(); goto beg; } else if( keytab[type].keyval==GSIZE ){ globsize(); goto beg; } else if( keytab[type].keyval==GFONT ) { globfont(); goto beg; } else return( keytab[type].keyval ); } getstr(s,c) char *s, c; { for (sp=0; c!=' ' && c!='\t' && c!='\n' && c!='{' && c!='}' && c!='"' && c!='~' && c!='^' && c!=righteq; ) { if(c == '\\') if((c = getc()) != '"')s[sp++] = '\\'; s[sp++] = c; if( sp>=SSIZE ) error(FATAL,"token %.20s... too long",s); c = getc(); } if( c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq ) peek = c; s[sp]='\0'; yylval = s; } lookup(str,tbl) char *str; struct { char *name; char *val; } tbl[]; { register i,j, r; for(i=0; tbl[i].name!=0; i++){ /* table of tbl wds */ for( j=0; (r=tbl[i].name[j])==str[j] && r!='\0'; j++); if( r == str[j] ) return(i); } return( -1 ); } cstr(s,quote) char *s; int quote; { int del,c,i; while((del=getc()) == ' ' || del == '\t' || del == '\n'); if(quote) for(i=0; (c=getc()) != del;) s[i++] = c; else { s[0] = del; for(i=1; (c=getc())!=' ' && c!= '\t' && c!='\n';) s[i++]=c; } s[i] = '\0'; return(s); } define(type) int type; { /* char *alloc (); */ int i, c; while( (c=getc())==' ' || c=='\n' ); getstr(token,c); if( type == DEFINE ) { if((i = lookup(token,deftab)) >= 0){ yyval = i; free(deftab[yyval].sptr); } else { yyval = ptr++; for(i=0; token[i] != '\0'; i++); deftab[yyval].nptr = alloc(i+1); for(i=0; deftab[yyval].nptr[i]=token[i]; i++); } if(dbg)printf(".\tdefine %s\n",deftab[yyval].nptr); } cstr(token,1); if( type != DEFINE ) return; for(i=0; token[i] != '\0'; i++); deftab[yyval].sptr = alloc(i+1); for(i=0; deftab[yyval].sptr[i] = token[i]; i++); if(dbg)printf(".\tname %s defined as %s\n", deftab[yyval].sptr, deftab[yyval].sptr); } delim() { char *s; yyval = eqnreg = 0; cstr(token,0); lefteq = token[0]; righteq = token[1]; if( (lefteq == 'o' && righteq == 'f') || (lefteq == 'O' && righteq == 'F') ) lefteq = righteq = '\0'; } globsize() { extern int gsize; int c; while( (c=getc())==' ' || c=='\n' ); getstr(token,c); gsize = numb(token); yyval = eqnreg = 0; setps(gsize); } globfont() { extern int gfont; while( (gfont=getc())==' ' || gfont=='\n' ); yyval = eqnreg = 0; printf(".ft %c\n", gfont); } ab[yyval].sptr); } delim() { char *s; yyval = eqnreg = 0; cstr(token,0); lefteq = token[0]; righteq = token[1]; if( (lefteq == 'o' && righteq == 'f') || (lefteq == 'O' && righteq == 'F') ) lefteq = righteq = '\0'; } globsize() { extern int gsize; int c; while( (c=getc())==' ' || c\{# # int fromflg 0; \} %term CONTIG QTEXT SPACE THIN TAB %term MATRIX LCOL CCOL RCOL COL %term MARK LINEUP %term SUM INT PROD UNION INTER %term LPILE PILE CPILE RPILE ABOVE %term DEFINE TDEFINE NDEFINE DELIM GSIZE GFONT %right FROM TO %left OVER SQRT %right SUP SUB %right SIZE FONT ROMAN ITALIC BOLD FAT %right UP DOWN BACK FWD %left MQ MQ1 %left LEFT RIGHT %right DOT DOTDOT HAT TILDE BAR UNDER VEC DYAD %% stuff : eqn ={ putout($1); } | error ={ error(!FATAL, "syntax error in equation %d", first); }  | ={ eqnreg = 0; } ; eqn : box ={ if(dbg)printf(".\teqn: S%d\n",$1); } | eqn box ={ eqnbox($1,$2); } | eqn MARK ={ mark($1); } | MARK ={ mark(0); } | eqn LINEUP ={ lineup($1); } | LINEUP ={ lineup(0); } ; matrix : MATRIX ={ $$ = ct; } ; collist : column | collist column ; column : lcol MQ list MQ1 ={ column('L',$1,$3); } | ccol MQ list MQ1 ={ column('C',$1,$3); } | rcol MQ list MQ1 ={ column('R',$1,$3); } | col MQ list MQ1 ={ column('-',$1,$3); } ; lcol : LCOL ={ $$ = ct++; } ; ccol : CCOL ={ $$ = ct++; } ; rcol : RCOL ={ $$ = ct++; } ; col : COL ={ $$ = ct++; } ; sbox : sup box %prec SUP ={ $$ = $2; } ; tbox : to box %prec TO ={ $$ = $2; } | %prec FROM ={ $$ = 0; } ; box : box OVER box ={ boverb($1,$3); } | size box %prec SIZE ={ size($1, $2); } | font box %prec FONT ={ font($1, $2); } | FAT box ={ fatbox($2); } | SQRT box ={ sqrt($2); } | lpile MQ list MQ1 ={ lpile('L', $1, ct); ct = $1; } | cpile MQ list MQ1 ={ lpile('C', $1, ct); ct = $1; } | rpile MQ list MQ1 ={ lpile('R', $1, ct); ct = $1; } | pile MQ list MQ1 ={ lpile('-', $1, ct); ct = $1; } | box sub box sbox %prec SUB ={ if(dbg)printf(".\t sub box %d %d %d\n",$1,$3,$4); shift2($1, $3, $4); } | box sub box %prec SUB ={ bshiftb($1, $2, $3); } | box sup box %prec SUP ={ bshiftb($1, $2, $3); } | left eqn right ={ paren($1, $2, $3); } | pbox | box from box tbox %prec FROM ={ fromto($1,$3,$4); fromflg=0; } | box to box %prec TO ={ fromto($1, 0, $3); } | box diacrit ={ diacrit($1,$2); } | fwd box %prec UP ={ move(0,$1,$2); } | up box %prec UP ={ move(1,$1,$2); } | back box %prec UP ={ move(2,$1,$2); } | down box %prec UP ={ move(3,$1,$2); } | matrix MQ collist MQ1 ={ matrix($1,$3); } ; fwd : FWD text ={ $$ = numb($1); } ; up : UP text ={ $$ = numb($1); } ; back : BACK text ={ $$ = numb($1); } ; down : DOWN text ={ $$ = numb($1); } ; diacrit : HAT ={ $$ = 'H'; } | VEC ={ $$ = 'V'; } | DYAD ={ $$ = 'Y'; } | BAR ={ $$ = 'B'; } | UNDER ={ $$ = 'N'; } /* under bar */ | DOT ={ $$ = 'D'; } | TILDE ={ $$ = 'T'; } | DOTDOT ={ $$ = 'U'; } /* umlaut = double dot */ ; from : FROM ={ $$=ps; ps =- 3; fromflg = 1; if(dbg)printf(".\tfrom: old ps %d, new ps %d, fflg %d\n", $$,ps,fromflg); } ; to : TO ={ $$=ps; if(fromflg==0)ps =- 3; if(dbg)printf(".\tto: old ps %d, new ps %d\n",$$,ps); } ; left : LEFT text ={ $$ = $2->c1; } | LEFT MQ ={ $$ = '{'; } ; right : RIGHT text ={ $$ = $2->c1; } | RIGHT MQ1 ={ $$ = '}'; } | ={ $$ = 0; } ; list : eqn ={ lp[ct++] = $1; } | list ABOVE eqn ={ lp[ct++] = $3; } ; lpile : LPILE ={ $$=ct; } ; cpile : CPILE ={ $$=ct; } ; pile : PILE ={ $$=ct; } ; rpile : RPILE ={ $$=ct; } ; size : SIZE text ={ $$=ps; if ($2->c1 == '+') ps =+ numb($2); else if ($2->c1 == '-') ps =- numb($2); else ps = numb($2); } ; font : ROMAN ={ setfont('R', 0); } | ITALIC ={ setfont('I', 0); } | BOLD ={ setfont('B', 0); } | FONT text ={ setfont($2->c1, $2->c2); } ; sub : SUB ={ shift(1); } ; sup : SUP ={ shift(-1); } ; pbox : MQ eqn MQ1 ={ $$ = $2; } | QTEXT ={ text('q',$1); } | CONTIG ={ text('c',$1); } | SPACE ={ text('~', $1); } | THIN ={ text('^', $1); } | TAB ={ text('\t', $1); } | SUM ={ funny('S'); } | PROD ={ funny('P'); } | INT ={ funny('I'); } | UNION ={ funny('U'); } | INTER ={ funny('A'); } /* intersection */ ; text : CONTIG | QTEXT | SPACE ={ $$ = & "\\|\\|"; } | THIN ={ $$ = & "\\|"; } ; %% FONT text ={ setfont($2->c1, $2->c2); } ; sub : SUB ={ shift(1); } ; sup : SUP ={ shift(-1); } ; pbox : MQ eqn MQ1 ={ $$ = $2; } | QTEX#define FATAL 1 #ifdef gcos #define fout cout #define fin cin #define close cclose #define exit cexit #define signal wdleng #define flush wdleng #define dup(n) n #define alloc(n) calloc(n, 1) #define free(p) cfree(p, 0, 0) #define open(f,m) copen(f, m==1 ? 'w' : 'r') #endif #define VERT(n) ((((n)+1)/3)*3) extern int dbg; extern int ct; extern int lp[40]; extern int used[100]; /* available registers */ extern int ps; /* dflt init pt size */ extern int deltaps; /* default change in ps */ extern int ft; /* dflt font */ extern int first; extern int fout, fin; extern int ifile; extern int linect; /* line number in file */ extern int eqline; /* line where eqn started */ extern int svargc; extern char **svargv; extern int eht[100]; extern int ebase[100]; extern int lfont[100]; extern int rfont[100]; struct { char c1; char c2; }; extern int yyval; extern int *yypv; extern int yylval; extern int tht[30]; extern int tbase[30]; extern int ptr; extern struct { char *nptr; char *sptr; } deftab[100]; extern int eqnreg, eqnht; extern int lefteq, righteq; extern int lastchar; /* last character read by lex */ * line number in file */ extern int eqline; /* line where eqn started */ extern int svargc; extern char **svargv; extern int eht[100]; extern int ebase[100]; extern int lfont[100]; extern int rfont[100]; struct { char c1; char c2; }; extern int yyval; extern int *yypv; extern int yylval; extern int tht[30]; extern int tbase[30]; extern int ptr; extern struct { char *nptr; char *sptr; } deftab[100]; extern int eqnreg,int dbg; int lp[80]; /* stack for things like piles and matrices */ int ct; /* pointer to lp */ int used[100]; /* available registers */ int ps; /* dflt init pt size */ int deltaps 3; /* default change in ps */ int ft; /* dflt font */ int first; int ifile; int linect; /* line number in file */ int eqline; /* line where eqn started */ int svargc; char **svargv; int eht[100]; int ebase[100]; int lfont[100]; int rfont[100]; int tht[30]; int tbase[30]; int ptr; struct { char *nptr; char *sptr; } deftab[100]; int eqnreg, eqnht; int lefteq, righteq; int lastchar; /* last character read by lex */ to lp */ int used[100]; /* available registers */ int ps; /* dflt init pt size */ int deltaps 3; /* default change in ps */ int ft; /* dflt font */ int first; int ifile; int linect; /* line number in file */ int eqline; /* line where eqn started */ int svargc; char **svargv; int eht[100]; int ebase[100]; int lfont[100]; int rfont[100]; int tht[30]; int tbase[30]; int ptr; struct { char *nptr; char *sptr; } deftab[100]; # include "e.h" boverb(p1, p2) int p1, p2; { int h, b, treg, d; treg = oalloc(); yyval = p1; d = (ps*6*3) / 10; /* 0.3m */ h = eht[p1] + eht[p2] + VERT(d); b = eht[p2] - d; if(dbg)printf(".\tb:bob: S%d <- S%d over S%d; b=%d, h=%d\n", yyval, p1, p2, b, h); nrwid(p1, ps, p1); nrwid(p2, ps, p2); printf(".nr %d \\n(%d\n", treg, p1); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2); printf(".nr %d \\n(%d+\\s%d.5m\\s0\n", treg, treg, ps); printf(".ds %d \\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d\\\n", yyval, eht[p2]-ebase[p2]-d, treg, p2, p2); printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\*(%d\\\n", p2, p1, -(eht[p2]-ebase[p2]+d+ebase[p1]), p1); printf("\\h'-\\n(%du-\\n(%du/2u+.1m'\\v'%du'\\l'\\n(%du-.2m'\\h'.1m'\\v'%du'\n", treg, p1, ebase[p1]+d, treg, d); ebase[yyval] = b; eht[yyval] = h; lfont[yyval] = rfont[yyval] = 0; ofree(p2); ofree(treg); } bshiftb(p1, dir, p2) int p1, dir, p2; { int shval, sh1, sh2, effps, effps2, d1, h1, b1, h2, b2, h; int diffps; yyval = p1; h1 = eht[p1]; b1 = ebase[p1]; h2 = eht[p2]; b2 = ebase[p2]; effps = ps>6 ? ps : 6; effps2 = (ps+deltaps)>6 ? ps+deltaps : 6; diffps = deltaps; sh1 = sh2 = ""; if( dir > 0 ) { /* subscript */ /* top 1/2m above bottom of main box */ d1 = VERT( (effps2*6)/2 ); shval = - d1 + h2 - b2; if( d1+b1 > h2 ) /* move little sub down */ shval = b1-b2; ebase[yyval] = b1 + max(0, h2-b1-d1); eht[yyval] = h1 + max(0, h2-b1-d1); if (rfont[p1] == 'I' && lfont[p2] == 'R') sh1 = "\\|"; if (rfont[p2] == 'I') sh2 = "\\|"; } else { /* superscript */ /* 4/10 up main box */ d1 = VERT( (effps*6*2)/10 ); ebase[yyval] = b1; shval = -VERT( (4 * (h1-b1)) / 10 ) - b2; if( VERT(4*(h1-b1)/10) + h2 < h1-b1 ) /* raise little super */ shval = -(h1-b1) + h2-b2 - d1; eht[yyval] = h1 + max(0, h2-VERT((6*(h1-b1))/10)); if (rfont[p1] == 'I') sh1 = "\\|"; } if(dbg)printf(".\tb:b shift b: S%d <- S%d vert %d S%d vert %d; b=%d, h=%d\n", yyval, p1, shval, p2, -shval, ebase[yyval], eht[yyval]); printf(".as %d \\v'%du'\\s-%d%s\\*(%d%s\\s+%d\\v'%du'\n", yyval, shval, diffps, sh1, p2, sh2, diffps, -shval); ps =+ deltaps; if (rfont[p2] == 'I') rfont[p1] = 0; else rfont[p1] = rfont[p2]; ofree(p2); } eqnbox(p1, p2) int p1, p2; { int b, h, sh; yyval = p1; b = max(ebase[p1], ebase[p2]); eht[yyval] = h = b + max(eht[p1]-ebase[p1], eht[p2]-ebase[p2]); ebase[yyval] = b; if(dbg)printf(".\te:eb: S%d <- S%d S%d; b=%d, h=%d\n", yyval, p1, p2, b, h); if (rfont[p1] == 'I' && lfont[p2] == 'R')  sh = "\\|"; else sh = ""; printf(".as %d \"%s\\*(%d\n", yyval, sh, p2); rfont[p1] = rfont[p2]; ofree(p2); } size(p1, p2) int p1, p2; { /* old size in p1, new in ps */ yyval = p2; if(dbg)printf(".\tb:sb: S%d <- \\s%d S%d \\s%d; b=%d, h=%d\n", yyval, ps, p2, p1, ebase[yyval], eht[yyval]); printf(".ds %d \\s%d\\*(%d\\s%d\n", yyval, ps, p2, p1); ps = p1; } numb(p1) char *p1; { int i, n, c; for(i=n=0; (c=p1[i++])!='\0'; ) if( c>='0' && c<='9' ) n = n*10 + c-'0'; if(dbg)printf(".\tnumb: %s %d\n", p1, n); return( n ); } setfont(ch1, ch2) char ch1, ch2; { /* temporarily ignoring two-char font names */ yyval = ft; ft = ch1; printf(".ft %c\n", ch1); if(dbg)printf(".\tsetfont %c\n", ch1); } font(p1, p2) int p1, p2; { /* old font in p1, new in ft */ yyval = p2; lfont[yyval] = rfont[yyval] = ft=='I' ? 'I' : 'R'; if(dbg)printf(".\tb:fb: S%d <- \\f%c S%d \\f%c b=%d,h=%dlf=%c,rf=%c\n", yyval, ft, p2, p1, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]); printf(".ds %d \\f%c\\*(%d\\f%c\n", yyval, ft, p2, p1); ft = p1; printf(".ft %c\n", ft); } fatbox(p) int p; { int sh; yyval = p; sh = ps / 4; nrwid(p, ps, p); printf(".ds %d \\*(%d\\h'-\\n(%du+%du'\\*(%d\n", p, p, p, sh, p); if(dbg)printf(".\tfat %d, sh=%d\n", p, sh); } shift(p1) int p1; { ps =- deltaps; yyval = p1; if(dbg)printf(".\tshift: %d;ps=%d\n", yyval, ps); } sqrt(p2) int p2; { int nps; nps = ((eht[p2]*9)/10+5)/6; yyval = p2; eht[yyval] = VERT( (nps*6*12)/10 ); if(dbg)printf(".\tsqrt: S%d <- S%d;b=%d, h=%d\n", yyval, p2, ebase[yyval], eht[yyval]); if (rfont[yyval] == 'I') printf(".as %d \\|\n", yyval); nrwid(p2, ps, p2); printf(".ds %d \\v'%du'\\s%d\\v'-.2m'\\(sr\\l'\\n(%du\\(rn'\\v'.2m'\\s%d", yyval, ebase[p2], nps, p2, ps); printf("\\v'%du'\\h'-\\n(%du'\\*(%d\n", -ebase[p2], p2, p2); } lpile(type, p1, p2) int type, p1, p2; { int bi, hi, i, gap, h, b, j, nlist, nlist2, mid; yyval = oalloc(); gap = VERT( (ps*6*4)/10 ); /* 4/10 m between blocks */ if( type=='-' ) gap = 0; nlist = p2 - p1; nlist2 = (nlist+1)/2; mid = p1 + nlist2 -1; h = 0; for( i=p1; imid; i-- ) b =+ eht[lp[i]] + gap; ebase[yyval] = (nlist%2) ? b + ebase[lp[mid]] : b - VERT( (ps*6*5)/10 ) - gap; if(dbg) { printf(".\tS%d <- %c pile of:", yyval, type); for( i=p1; i\\n(%d .nr %d \\n(%d\n", lp[i], yyval, yyval, lp[i]); } printf(".ds %d \\v'%du'\\h'%du*\\n(%du'\\\n", yyval, ebase[yyval], type=='R' ? 1 : 0, yyval); for(i = p2-1; i >=p1; i--) { hi = eht[lp[i]]; bi = ebase[lp[i]]; switch(type) { case 'L': printf("\\v'%du'\\*(%d\\h'-\\n(%du'\\v'0-%du'\\\n", -bi, lp[i], lp[i], hi-bi+gap); continue; case 'R': printf("\\v'%du'\\h'-\\n(%du'\\*(%d\\v'0-%du'\\\n", -bi, lp[i], lp[i], hi-bi+gap); continue; case 'C': case '-': printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\*(%d", -bi, yyval, lp[i], lp[i]); printf("\\h'-\\n(%du-\\n(%du/2u'\\v'0-%du'\\\n", yyval, lp[i], hi-bi+gap); continue; } } printf("\\v'%du'\\h'%du*\\n(%du'\n", eht[yyval]-ebase[yyval]+gap, type!='R' ? 1 : 0, yyval); for( i=p1; i6 ? ps+deltaps:6; eht[p3] = h3 = VERT( (eht[p3] * effps) / (ps>6 ? ps : 6) ); ps =+ deltaps; effps2 = (ps+deltaps)>6 ? ps+deltaps:6; h1 = eht[p1]; b1 = ebase[p1]; h2 = eht[p2]; b2 = ebase[p2]; b3 = ebase[p3]; d1 = VERT( (effps2*6)/2 ); subsh = -d1+h2-b2; if( d1+b1 > h2 ) /* move little sub down */ subsh = b1-b2; supsh = -VERT( (4*(h1-b1))/10 ) - b3; d2 = VERT( (effps*6*2)/10 ); if( VERT(4*(h1-b1)/10)+h3 < h1-b1 ) supsh = -(h1-b1) + (h3-b3) - d2; eht[yyval] = h1 + max(0, h3-VERT( (6*(h1-b1))/10 )) + max(0, h2-b1-d1); ebase[yyval] = b1+max(0, h2-b1-d1); if (rfont[p1] == 'I' && lfont[p2] == 'R') printf(".ds %d \\|\\*(%d\n", p2, p2); if (rfont[p2] == 'I') printf(".as %d \\|\n", p2); nrwid(p2, effps, p2); if (rfont[p1] == 'I' && lfont[p3] == 'R') printf(".ds %d \\|\\|\\*(%d\n", p3, p3); else printf(".ds %d \\|\\*(%d\n", p3, p3); nrwid(p3, effps, p3); printf(".nr %d \\n(%d\n", treg, p3); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, treg, treg, p2); printf(".as %d \\v'%du'\\s%d\\*(%d\\h'-\\n(%du'\\v'%du'\\\n", p1, subsh, effps, p2, p2, -subsh+supsh); printf("\\s%d\\*(%d\\h'-\\n(%du+\\n(%du'\\s%d\\v'%du'\n", effps, p3, p3, treg, effps2, -supsh); ps =+ deltaps; if (rfont[p2] == 'I') rfont[yyval] = 0; /* lie */ ofree(p2); ofree(p3); ofree(treg); } \|\\|\\*(%d\n", p3, p3); else printf(".ds %d \\|\\*(%d\n", p3, p3); nrwid(p3, effps, p3# include "e.h" fromto(p1, p2, p3) int p1, p2, p3; { int h, b, h1, b1, pss; yyval = oalloc(); lfont[yyval] = rfont[yyval] = 0; h1 = eht[yyval] = eht[p1]; b1 = ebase[p1]; b = 0; pss = ps; ps =+ 3; nrwid(p1, ps, p1); printf(".nr %d \\n(%d\n", yyval, p1); if( p2>0 ) { nrwid(p2, pss, p2); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p2, yyval, yyval, p2); eht[yyval] =+ eht[p2]; b = eht[p2]; } if( p3>0 ) { nrwid(p3, pss, p3); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", p3, yyval, yyval, p3); eht[yyval] =+ eht[p3]; } printf(".ds %d ", yyval); /* bottom of middle box */ if( p2>0 ) { printf("\\v'%du'\\h'\\n(%du-\\n(%du/2u'\\s%d\\*(%d\\s%d", eht[p2]-ebase[p2]+b1, yyval, p2, pss, p2, ps); printf("\\h'-\\n(%du-\\n(%du/2u'\\v'%du'\\\n", yyval, p2, -(eht[p2]-ebase[p2]+b1)); } printf("\\h'\\n(%du-\\n(%du/2u'\\*(%d\\h'\\n(%du-\\n(%du/2u'\\\n", yyval, p1, p1, yyval, p1); if( p3>0 ) { printf("\\v'%du'\\h'-\\n(%du-\\n(%du/2u'\\s%d\\*(%d\\s%d\\h'\\n(%du-\\n(%du/2u'\\v'%du'\\\n", -(h1-b1+ebase[p3]), yyval, p3, pss, p3, ps, yyval, p3, (h1-b1+ebase[p3])); } printf("\n"); ebase[yyval] = b + b1; if(dbg)printf(".\tfrom to: S%d <- %d f %d t %d; h=%d b=%d\n", yyval, p1, p2, p3, eht[yyval], ebase[yyval]); ofree(p1); if( p2>0 ) ofree(p2); if( p3>0 ) ofree(p3); } paren(leftc, p1, rightc) int p1, leftc, rightc; { int n, m, h1, j, b1, v; h1 = eht[p1]; b1 = ebase[p1]; yyval = p1; lfont[yyval] = rfont[yyval] = 0; n = (h1+(6*ps-1))/(6*ps); if( n<2 ) n = 1; m = n-2; if( leftc=='{' ){ n = n%2 ? n : ++n; if( n<3 ) n=3; m = n-3; } eht[yyval] = VERT(6 * ps * n); ebase[yyval] = b1 + (eht[yyval]-h1)/2; v = b1 - h1/2 + VERT( (ps*6*4)/10 ); printf(".ds %d \\|\\v'%du'", yyval, v); switch( leftc ) { case 'n': /* nothing */ case '\0': break; case 'f': /* floor */ if (n <= 1) printf("\\(lf"); else brack(m, "\\(bv", "\\(bv", "\\(lf"); break; case 'c': /* ceiling */ if (n <= 1) printf("\\(lc"); else brack(m, "\\(lc", "\\(bv", "\\(bv");  break; case '{': printf("\\b'\\(lt"); for(j = 0; j < m; j =+ 2) printf("\\(bv"); printf("\\(lk"); for(j = 0; j < m; j =+ 2) printf("\\(bv"); printf("\\(lb'"); break; case '(': brack(m, "\\(lt", "\\(bv", "\\(lb"); break; case '[': brack(m, "\\(lc", "\\(bv", "\\(lf"); break; default: brack(m, &leftc, &leftc, &leftc); break; } printf("\\v'%du'\\*(%d", -v, p1); if( rightc ) { printf("\\|\\v'%du'", v); switch( rightc ) { case 'f': /* floor */ if (n <= 1) printf("\\(rf"); else brack(m, "\\(bv", "\\(bv", "\\(rf"); break; case 'c': /* ceiling */ if (n <= 1) printf("\\(rc"); else brack(m, "\\(rc", "\\(bv", "\\(bv"); break; case '}': printf("\\b'\\(rt"); for(j = 0; j< m; j =+ 2)printf("\\(bv"); printf("\\(rk"); for(j = 0; j< m; j =+ 2) printf("\\(bv"); printf("\\(rb'"); break; case ']': brack(m, "\\(rc", "\\(bv", "\\(rf"); break; case ')': brack(m, "\\(rt", "\\(bv", "\\(rb"); break; default: brack(m, &rightc, &rightc, &rightc); break; } printf("\\v'%du'", -v); } printf("\n"); if(dbg)printf(".\tcurly: h=%d b=%d n=%d v=%d l=%c, r=%c\n", eht[yyval], ebase[yyval], n, v, leftc, rightc); } brack(m, t, c, b) int m; char *t, *c, *b; { int j; printf("\\b'%s", t); for( j=0; j1 .nr 10 \\s%d.25m\\s0\n", effps); printf(".nr %d \\s%d.1m\\s0\n", t, effps); /* horiz shift if high */ printf(".if \\n(ct>1 .nr %d \\s%d.15m\\s0\n", t, effps); switch(type) { case 'V': /* vec */ printf(".ds %d \\v'-.4m'\\s%d\\(->\\s0\\v'.4m'\n", c, max(effps-3, 6)); break; case 'Y': /* dyad */ printf(".ds %d \\v'-.4m'\\s%d\\z\\(<-\\(->\\s0\\v'.4m'\n", c, max(effps-3, 6)); break; case 'H': /* hat */ printf(".ds %d ^\n", c); break; case 'T': /* tilde */ printf(".ds %d ~\n", c); break; case 'D': /* dot */ printf(".ds %d \\s%d\\v'-.67m'.\\v'.67m'\\s0\n", c, effps); break; case 'U': /* umlaut = dotdot */ printf(".ds %d \\s%d\\v'-.67m'..\\v'.67m\\s0'\n", c, effps); break; case 'B': /* bar */ printf(".ds %d \\s%d\\v'.18m'\\h'.05m'\\l'\\n(%du-.1m\\(rn'\\h'.05m'\\v'-.18m'\\s0\n", c, effps, p1); break; case 'N': /* under */ printf(".ds %d \\l'\\n(%du\\(ul'\n", c, p1); printf(".nr %d 0\n", t); printf(".nr 10 0-%d\n", -ebase[p1]); break; } nrwid(c, ps, c); if (lfont[p1] != 'I') printf(".nr %d 0\n", t); printf(".as %d \\h'-\\n(%du-\\n(%du/2u+\\n(%du'\\v'0-\\n(10u'\\*(%d", p1, p1, c, t, c); printf("\\v'\\n(10u'\\h'-\\n(%du+\\n(%du/2u-\\n(%du'\n", c, p1, t); ofree(c); ofree(t); } move(dir, amt, p) int dir, amt; char *p; { /* 0=fwd, 1=up, 2=back, 3=down */ int a, a1, a2; yyval = p; a1 = amt/100; a2 = amt%100; printf(".ds %d ", yyval); if( dir==0 || dir==2 ) /* fwd, back */ printf("\\h'%s%d.%dm'\\*(%d\n", (dir==2) ? "-" : "", a1, a2, p); else if (dir == 1) printf("\\v'-%d.%dm'\\*(%d\\v'%d.%dm'\n", a1, a2, p, a1, a2); else if (dir == 3) printf("\\v'%d.%dm'\\*(%d\\v'-%d.%dm'\n", a1, a2, p, a1, a2); a = (ps * 6 * amt) / 100; /* if (dir == 1 || dir == 3) eht[yyval] =+ a; if( dir==1 ) ebase[yyval] =- a; else if( dir==3 ) ebase[yyval] =+ a; */ if(dbg)printf(".\tmove %d dir %d amt %d; h=%d b=%d\n", p, dir, amt, eht[yyval], ebase[yyval]); } funny(n) int n; { int f, t; yyval = oalloc(); t = 'S'; switch(n) { case 'S': f = "\\(*S"; break; case 'U': f = "\\(cu"; break; case 'A': /* intersection */ f = "\\(ca"; break; case 'P': f = "\\(*P"; break; case 'I': f = "\\(is"; t = 'I'; printf(".ds %d \\s%d\\v'.1m'\\s+4%s\\s-4\\v'-.1m'\\s%d\n", yyval, ps, f, ps); eht[yyval] = VERT( (((ps+4)*12)/10)*6 ); ebase[yyval] = VERT( (ps*6*3)/10 );  break; default: t = 0; } if( t == 'S' ) { printf(".ds %d \\s%d\\v'.3m'\\s+5%s\\s-5\\v'-.3m'\\s%d\n", yyval, ps, f, ps); eht[yyval] = VERT( (ps+5)*6 -(ps*6*2)/10 ); ebase[yyval] = VERT( (ps*6*3)/10 ); } if(dbg)printf(".\tfunny: S%d <- %s; h=%d b=%d\n", yyval, f, eht[yyval], ebase[yyval]); lfont[yyval] = rfont[yyval] = 'R'; } rintf(".ds %d \\s%d\\v'.1m'\\s+4%s\\s-4\\v'-.1m'\\s%d\n", yyval, ps, f, ps); eht[yyval] = VERT( (((ps+4)*12)/10)*6 ); ebase[yyval] = VERT( (ps*6*3)/10 ); # include "e.h" struct { char *res; char *resval; } restab[] { ">=", "\\(>=", "<=", "\\(<=", "==", "\\(==", "!=", "\\(!=", "+-", "\\(+-", "->", "\\(->", "<-", "\\(<-", "<<", "<\\h'-.3m'<", ">>", ">\\h'-.3m'>", "inf", "\\(if", "infinity", "\\(if", "partial", "\\(pd", "half", "\\fR\\(12\\fP", "prime", "\\fR\\(fm\\fP", "approx", "\\v'-.2m'\\z\\(ap\\v'.25m'\\(ap\\v'-.05m'", "nothing", "", "cdot", "\\v'-.3m'.\\v'.3m'", "times", "\\(mu", "del", "\\(gr", "grad", "\\(gr", "...", "\\v'-.3m'\\ .\\ .\\ .\\ \\v'.3m'", ",...,", ",\\ .\\ .\\ .\\ ,\\|", "alpha", "\\(*a", "beta", "\\(*b", "gamma", "\\(*g", "GAMMA", "\\(*G", "delta", "\\(*d", "DELTA", "\\(*D", "epsilon", "\\(*e", "omega", "\\(*w", "OMEGA", "\\(*W", "lambda", "\\(*l", "LAMBDA", "\\(*L", "mu", "\\(*m", "nu", "\\(*n", "theta", "\\(*h", "THETA", "\\(*H", "phi", "\\(*f", "PHI", "\\(*F", "pi", "\\(*p", "PI", "\\(*P", "sigma", "\\(*s", "SIGMA", "\\(*S", "xi", "\\(*c", "XI", "\\(*C", "zeta", "\\(*z", "iota", "\\(*i", "eta", "\\(*y", "kappa", "\\(*k", "rho", "\\(*r", "tau", "\\(*t", "omicron", "\\(*o", "upsilon", "\\(*u", "UPSILON", "\\(*U", "psi", "\\(*q", "PSI", "\\(*Q", "chi", "\\(*x", "and", "\\fRand\\fP", "for", "\\fRfor\\fP", "if", "\\fRif\\fP", "Re", "\\fRRe\\fP", "Im", "\\fRIm\\fP", "sin", "\\fRsin\\fP", "cos", "\\fRcos\\fP", "tan", "\\fRtan\\fP", "arc", "\\fRarc\\fP", "sinh", "\\fRsinh\\fP", "coth", "\\fRcoth\\fP", "tanh", "\\fRtanh\\fP", "cosh", "\\fRcosh\\fP", "lim", "\\fRlim\\fP", "log", "\\fRlog\\fP", "max", "\\fRmax\\fP", "min", "\\fRmin\\fP", "ln", "\\fRln\\fP", "exp", "\\fRexp\\fP", "det", "\\fRdet\\fP", 0, 0 }; int csp; int psp; #define CSSIZE 400 char cs[420]; int lf, rf; /* temporary spots for left and right fonts */ text(t,p1) int t; char *p1; { int i,j,c; yyval = oalloc(); ebase[yyval] = 0; eht[yyval] = VERT(6 * ((ps>6)?ps:6)); /* ht in machine units */ lfont[yyval] = rfont[yyval] = 'R'; if( t=='q' ) j = p1; else if ( t == '~' ) j = &"\\|\\|"; else if ( t == '^' ) j = &"\\|"; else if ( t == '\t' ) j = &"\\t"; else if( (i=lookup(p1,restab))>=0 ) { j = restab[i].resval; } else { lf = rf = 0; for( csp=psp=0; (c=p1[psp++])!='\0'; ){ rf = trans(c, p1); if (lf == 0) lf = rf; /* save first */ if( csp>CSSIZE ) error(FATAL,"converted token %.25s... too long",p1); } cs[csp] = '\0'; j = cs; lfont[yyval] = lf; rfont[yyval] = rf; } if(dbg)printf(".\t%ctext: S%d <- %s; b=%d,h=%d,lf=%c,rf=%c\n", t, yyval, j, ebase[yyval], eht[yyval], lfont[yyval], rfont[yyval]); printf(".ds %d \"%s\n", yyval, j); } trans(c,p1) int c; char *p1; { int f; f = 'R'; switch( c){ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case ':': case ';': case '!': case '%': case '(': case '[': case ')': case ']': if (rf == 'I') shim(); roman(c); break; case '.': if (rf == 'R') roman(c); else cs[csp++] = c; f = rf; break; case '|': if (rf == 'I') shim(); shim(); roman(c); shim(); break; case '=': if (rf == 'I') shim(); name4('e','q'); break; case '+': if (rf == 'I') shim(); name4('p', 'l'); break; case '>': case '<': if (rf == 'I') shim(); if( p1[psp]=='=' ){ /* look ahead for == <= >= */ name4(c,'='); psp++; } else { cs[csp++] = c; } break; case '-': if (rf == 'I') shim(); if( p1[psp]=='>' ){ name4('-','>'); psp++; } else { name4('m','i'); } break; case '/': if (rf == 'I') shim(); name4('s','l'); break; case '~': case ' ': shim(); shim(); break; case '^': shim(); break; case '\\': /* troff - pass 2 or 3 more chars */ if (rf == 'I') shim(); cs[csp++] = c; cs[csp++] = c = p1[psp++]; cs[csp++] = p1[psp++]; if( c=='(' ) cs[csp++] = p1[psp++]; if( c=='*' && cs[csp-1] == '(' ){ cs[csp++] = p1[psp++]; cs[csp++] = p1[psp++]; } break; case '\'': cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = rf=='I' ? 'I' : 'R'; name4('f','m'); cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P'; f = rf=='I' ? 'I' : 'R'; break; case 'f': cs[csp++] = '\\'; cs[csp++] = '^'; cs[csp++] = 'f'; cs[csp++] = '\\'; cs[csp++] = '^'; f = 'I'; break; case 'j': cs[csp++] = '\\'; cs[csp++] = '^'; cs[csp++] = 'j'; f = 'I'; break; default: cs[csp++] = c; f = ft=='I' ? 'I' : 'R'; break; } return(f); } shim() { cs[csp++] = '\\'; cs[csp++] = '|'; } roman(c) int c; { cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'R'; cs[csp++] = c; cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'P'; } name4(c1,c2) int c1,c2; { cs[csp++] = '\\'; cs[csp++] = '('; cs[csp++] = c1; cs[csp++] = c2; } s[csp++] = '\\'; cs[csp++] = '^'; f = 'I'; break; case 'j': cs[csp++] = '\\'; cs[csp++] = '^'; cs[csp++] = 'j'; f = 'I'; break; default: cs[csp++] = c; f = ft=='I' ? 'I' : 'R'; break; } return(f); } shim() { cs[csp++] = '\\'; cs[csp++] = '|'; } roman(c) int c; { cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] = 'R'; cs[csp++] = c; cs[csp++] = '\\'; cs[csp++] = 'f'; cs[csp++] =# include "e.h" # define SIGPIPE 13 /* troff has stopped reading */ int gsize 10; int gfont 'I'; char in[600]; /* input buffer */ int exit(); int noeqn; main(argc,argv) int argc; char *argv[];{ int i, type; first = 0; lefteq = righteq = '\0'; signal(SIGPIPE, &exit); setfile(argc,argv); while( (type=getline(in)) != '\0' ){ eqline = linect; if( in[0]=='.' && in[1]=='E' && in[2]=='Q' ){ for( i=11; i<100; used[i++]=0 ); printf("%s",in); printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); init();  yyparse(); if( eqnreg>0 ){ printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg); printf(".if \\n(%d>\\n(.l .tm too-long eqn, file %s, between lines %d-%d\n", eqnreg, svargv[ifile], eqline, linect); printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht); printf(".rn %d 10\n", eqnreg); if(!noeqn)printf("\\*(10\n"); } printf(".ps \\n(99\n.ft \\n(98\n"); printf(".EN"); if( lastchar == '\0' ){ putchar('\n'); break; } if( putchar(lastchar) != '\n' ) while( putchar(getc()) != '\n' ); flush(); } else if( type == lefteq ) inline(); else printf("%s",in); } flush(); exit(0); } getline(s) char *s; { char c; while((*s++=c=getc())!='\n' && c!='\0' && c!=lefteq ); if( c==lefteq ) s--; *s++ = '\0'; return(c); } inline() { int i,j,ds,t; printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); ds = oalloc(); printf(".ds %d \"\n", ds); do{ printf(".as %d \"%s\n", ds, in); init(); yyparse(); if( eqnreg > 0 ) { printf(".as %d \\*(%d\n", ds, eqnreg); ofree(eqnreg); } printf(".ps \\n(99\n.ft \\n(98\n"); } while( (t=getline(in)) == lefteq ); printf(".as %d \"%s", ds, in); printf(".ps \\n(99\n.ft \\n(98\n"); printf("\\*(%d\n", ds); ofree(ds); flush(); } putout(p1) int p1; { extern int gsize, gfont; int before, after; if(dbg)printf(".\tanswer <- S%d, h=%d,b=%d\n",p1, eht[p1], ebase[p1]); eqnht = eht[p1]; printf(".ds %d \\x'0'", p1); /* suppposed to leave room for a subscript or superscript */ before = eht[p1] - ebase[p1] - VERT((ps*6*12)/10); if( before > 0 ) printf("\\x'0-%du'", before); printf("\\f%c\\s%d\\*(%d\\s\\n(99\\f\\n(98",gfont,gsize,p1); after = ebase[p1] - VERT((ps*6*2)/10); if( after > 0 ) printf("\\x'%du'", after); putchar('\n'); eqnreg = p1; } max(i,j) int i,j; { return( i>j ? i : j ); } oalloc(){ int i; for( i=11; i<100; i++) if( used[i]++ == 0 ) return(i); error( FATAL, "no strings left", i); } ofree(n) int n; { used[n] = 0; } setps(p) int p; { printf(".ps %d\n", p); } nrwid(n1, p, n2) int n1, p, n2; { printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, p, n2); } setfile(argc, argv) int argc; char *argv[]; { svargc = --argc; svargv = argv; while( svargc > 0 && svargv[1][0] == '-'){ switch( svargv[1][1] ){ case 'd': lefteq=svargv[1][2]; righteq=svargv[1][3]; break; case 's': gsize = numb(&svargv[1][2]); break; case 'p': deltaps = numb(&svargv[1][2]); break; case 'f': gfont = svargv[1][2]; break; case 'e': noeqn++; break; default: dbg = 1; } svargc--; svargv++; } ptr = 0; fout = dup(1); ifile = 1; linect = 1; if( svargc <= 0 ) fin = dup(0); else if( (fin = open(svargv[1], 0)) < 0) error( FATAL,"can't open file %s", svargv[1]); } yyerror(){;} init(){ ct = 0; ps = gsize; ft = gfont; first++; setps(ps); printf(".ft %c\n", ft); } error(fatal, s1, s2) int fatal; char *s1, *s2; { int sfout; if( fatal>0 ) printf("fatal error: "); printf(s1,s2); printf(" file %s, between lines %d and %d\n", svargv[ifile], eqline, linect); flush(fout); sfout = fout; fout = 2; if( fatal>0 ) printf("fatal error: "); printf(s1,s2); printf(" file %s, between lines %d and %d\n", svargv[ifile], eqline, linect); flush(2); fout = sfout; if( fatal > 0 ) exit(1); } ps = gsize; ft = gfont; first++; setps(ps); printf(".ft %c\n", ft); } error(fatal, s1, s2) int fatal; char *s1, *s2; { int sfout; if( fatal>0 ) printf("fatal error: "); printf(s1,s2); printf(" file %s, between lines %d and %d\n", svargv[ifile], eqline, linect); flush(fout); sfout = fout; fout = 2; if( fatal>0 )#include "e.h" mark(n) int n; { if( n ) printf(".as %d \\k(97\n", n); else { yyval = oalloc(); printf(".ds %d \\k(97\n", yyval); nrwid(yyval, ps, yyval); eht[yyval] = eht[n]; ebase[yyval] = ebase[n]; lfont[yyval] = rfont[yyval] = 0; } if(dbg)printf(".\tmark %d as %d\n", n, yyval); } lineup(n) int n; { if( n ) { nrwid(n, ps, n); printf(".ds %d \\h'|\\n(97u-\\n(%du'\\*(%d\n", n, n, n); } else { yyval = oalloc(); printf(".ds %d \\h'|\\n(97u'\n", yyval); nrwid(yyval, ps, yyval);  eht[yyval] = eht[n]; ebase[yyval] = ebase[n]; lfont[yyval] = rfont[yyval] = 0; } if(dbg)printf(".\tlineup %d in %d\n", n, yyval); } nrwid(yyval, ps, yyval); eht[yyval] = eht[n]; ebase[yyval] = ebase[n]; lfont[yyval] = rfont[yyval] = 0; } if(dbg)printf(".\tmark %d as %d\n", n, yyval); } lineup(n) int n; { if( n ) { nrwid(n, ps, n); printf(".ds %d \\h'|\\n(97u-\\n(%du'\\*(%d\n", n, n, n); } else { yyval = oalloc(); printf(".ds %d \\h'|\\n(97u'\n", yyval); nrwid(yyval, ps, yyval); #include "e.h" column(type, p1, p2) int type, p1, p2; { int i, n; lp[p1] = ct - p1 - 1; if( dbg ){ printf(".\t%c column of", type); for( i=p1+1; i= 0){ lastchar = (peek<0) ? *swt[sw]++ : peek; peek = -1; if(lastchar != '\0')return(lastchar); peek = speek[sw--]; return(' '); } lastchar = (peek<0) ? getchar() : peek; if( lastchar=='\n' ) linect++; peek = -1; if( lastchar!= '\0' ) return(lastchar); if( ++ifile > svargc ){ peek = '\0'; return('\0'); } close(fin); linect = 1; if( (fin=open(svargv[ifile],0)) >= 0 ) goto loop; error(FATAL,"can't open file %s\n", svargv[ifile]); } yylex(){ int c, type; beg: while( (c=getc())==' ' || c=='\n'); yylval=c; switch(c){ case '\0': return('\0'); case '~': return(SPACE); case '^': return(THIN); case '\t': return(TAB); case '{': return(MQ); case '}': return(MQ1); case '"': for(sp=0; (c=getc())!='"'; ){ if(c !='\\')token[sp++]=c; else { if((c=getc())!= '"')token[sp++]='\\'; token[sp++] = c; } if( sp>=SSIZE ) error(FATAL,"quoted string %.20s... too long", token); } token[sp]='\0'; yylval= &token[0]; return(QTEXT); } if( c==righteq )  return('\0'); getstr(token, c); if((type = lookup(token,deftab)) >= 0){ if(sw >= 9) error(FATAL,"definitions nested > 9", sw); swt[++sw] = deftab[type].sptr; speek[sw] = peek; peek = -1; goto beg; } type = lookup(token,keytab); if( type < 0 ) return(CONTIG); if( keytab[type].keyval==DEFINE || keytab[type].keyval==NDEFINE ) { define(keytab[type].keyval); goto beg; } else if( keytab[type].keyval==DELIM ) { delim(); goto beg; } else if( keytab[type].keyval==GSIZE ){ globsize(); goto beg; } else if( keytab[type].keyval==GFONT ) { globfont(); goto beg; } else return( keytab[type].keyval ); } getstr(s,c) char *s, c; { for (sp=0; c!=' ' && c!='\t' && c!='\n' && c!='{' && c!='}' && c!='"' && c!='~' && c!='^' && c!=righteq; ) { if(c == '\\') if((c = getc()) != '"')s[sp++] = '\\'; s[sp++] = c; if( sp>=SSIZE ) error(FATAL,"token %.20s... too long",s); c = getc(); } if( c=='{' || c=='}' || c=='"' || c=='~' || c=='^' || c=='\t' || c==righteq ) peek = c; s[sp]='\0'; yylval = s; } lookup(str,tbl) char *str; struct { char *name; char *val; } tbl[]; { register i,j, r; for(i=0; tbl[i].name!=0; i++){ /* table of tbl wds */ for( j=0; (r=tbl[i].name[j])==str[j] && r!='\0'; j++); if( r == str[j] ) return(i); } return( -1 ); } cstr(s,quote) char *s; int quote; { int del,c,i; while((del=getc()) == ' ' || del == '\t' || del == '\n'); if(quote) for(i=0; (c=getc()) != del;) s[i++] = c; else { s[0] = del; for(i=1; (c=getc())!=' ' && c!= '\t' && c!='\n';) s[i++]=c; } s[i] = '\0'; return(s); } define(type) int type; { /* char *alloc (); */ int i, c; while( (c=getc())==' ' || c=='\n' ); getstr(token,c); if( type == DEFINE ) { if((i = lookup(token,deftab)) >= 0){ yyval = i; free(deftab[yyval].sptr); } else { yyval = ptr++; for(i=0; token[i] != '\0'; i++); deftab[yyval].nptr = alloc(i+1); for(i=0; deftab[yyval].nptr[i]=token[i]; i++); } if(dbg)printf(".\tdefine %s\n",deftab[yyval].nptr); } cstr(token,1); if( type != DEFINE ) return; for(i=0; token[i] != '\0'; i++); deftab[yyval].sptr = alloc(i+1); for(i=0; deftab[yyval].sptr[i] = token[i]; i++); if(dbg)printf(".\tname %s defined as %s\n", deftab[yyval].sptr, deftab[yyval].sptr); } delim() { char *s; yyval = eqnreg = 0; cstr(token,0); lefteq = token[0]; righteq = token[1]; if( (lefteq == 'o' && righteq == 'f') || (lefteq == 'O' && righteq == 'F') ) lefteq = righteq = '\0'; } globsize() { extern int gsize; int c; while( (c=getc())==' ' || c=='\n' ); getstr(token,c); if (token[0] == '+') gsize =+ numb(token); else if (token[0] == '-') gsize =- numb(token); else gsize = numb(token); yyval = eqnreg = 0; setps(gsize); ps = gsize; } globfont() { extern int gfont; while( (gfont=getc())==' ' || gfont=='\n' ); yyval = eqnreg = 0; printf(".ft %c\n", gfont); ft = gfont; } == 'o' && righteq == 'f') || (lefteq == 'O' && righteq == 'F') ) lefteq = righteq = '\0'; } globsize() { extern int gsize; int c; while( (c=getc())==' ' || c=#define FATAL 1 #ifdef gcos #define fout cout #define fin cin #define close cclose #define exit cexit #define signal wdleng #define flush wdleng #define dup(n) n #define alloc(n) calloc(n, 1) #define free(p) cfree(p, 0, 0) #define open(f,m) copen(f, m==1 ? 'w' : 'r') #endif #define VERT(n) (20*n) extern int dbg; extern int ct; extern int lp[40]; extern int used[100]; /* available registers */ extern int ps; /* dflt init pt size */ extern int ft; /* dflt font */ extern int first; extern int fout, fin; extern int ifile; extern int linect; /* line number in file */ extern int eqline; /* line where eqn started */ extern int svargc; extern char **svargv; extern int eht[100]; extern int ebase[100]; struct { char c1; char c2; }; extern int yyval; extern int *yypv; extern int yylval; extern int tht[30]; extern int tbase[30]; extern int ptr; extern struct { char *nptr; char *sptr; } deftab[100]; extern int eqnreg, eqnht; extern int lefteq, righteq; extern int lastchar; /* last character read by lex */ t, fin; exteint dbg; int lp[40]; /* stack for things like piles and matrices */ int ct; /* pointer to lp */ int used[100]; /* available registers */ int ps; /* dflt init pt size */ int ft; /* dflt font */ int first; extern int fout, fin; int ifile; int linect; /* line number in file */ int eqline; /* line where eqn started */ int svargc; char **svargv; int eht[100]; int ebase[100]; int tht[30]; int tbase[30]; int ptr; struct { char *nptr; char *sptr; } deftab[100]; int eqnreg, eqnht; int lefteq, righteq; int lastchar; /* last character read by lex */ hings like piles and matrices */ int ct; /* pointer to lp */ int used[100]; /* available registers */ int ps; /* dflt init pt size */ int ft; /* dflt font */ int first; extern int fout, fin; int ifile; int linect; /* line number in file */ int eqline; /* line where eqn started */ int svargc; char **svargv; int eht[100]; int ebase[100]; int tht[30]; int tbase[30]; int ptr; struct { char *nptr; char *sptr; } deftab[100]; int eqnreg, eqnht; int lefteq, righteq; int lastchar/ suftab - suffix table suftab: sufa+20 0 sufc+20 sufd+20 sufe+20 suff+20 sufg+20 sufh+20 sufi+20 0 sufk+20 sufl+20 sufm+20 sufn+20 sufo+20 sufp+20 0 sufr+20 sufs+20 suft+20 0 0 0 0 sufy+20 0 sufa: .byte 2,200+'t /-TA .byte 2,200+'s /-SA .byte 3,200+'t,'r /-TRA .byte 3,200+'d,'r /-DRA .byte 3,200+'b,'r /-BRA .byte 2,200+'p /-PA .byte 2,200+'n /-NA .byte 2,200+'m /-MA .byte 3,200+'p,'l /-PLA .byte 2,200+'l /-LA .byte 2,200+'k /-KA .byte 3,200+'t,'h /-THA .byte 3,200+'s,'h /-SHA .byte 2,200+'g /-GA .byte 2,200+'d /-DA .byte 2,200+'c /-CA .byte 2,200+'b /-BA .byte 0 sufc: .byte 4,'e,'t,200+'i /ET-IC .byte 7,'a,'l,200+'i,'s,200+'t,'i /AL-IS-TIC .byte 4,'s,200+'t,'i /S-TIC .byte 4,'p,200+'t,'i /P-TIC .byte 5,200+'l,'y,'t,200+'i /-LYT-IC .byte 4,'o,'t,200+'i /OT-IC .byte 5,'a,'n,200+'t,'i /AN-TIC .byte 4,'n,200+'t,'i /N-TIC .byte 4,'c,200+'t,'i /C-TIC .byte 4,'a,'t,200+'i /AT-IC .byte 4,'h,200+'n,'i /H-NIC .byte 3,'n,200+'i /N-IC .byte 3,'m,200+'i /M-IC .byte 4,'l,200+'l,'i /L-LIC .byte 4,'b,200+'l,'i /B-LIC .byte 4,200+'c,'l,'i /-CLIC .byte 3,'l,200+'i /L-IC .byte 3,'h,200+'i /H-IC .byte 3,'f,200+'i /F-IC .byte 3,'d,200+'i /D-IC .byte 3,200+'b,'i /-BIC .byte 3,'a,200+'i /A-IC .byte 3,200+'m,'a /-MAC .byte 3,'i,200+'a /I-AC .byte 0 sufd: .byte 4,200+'w,'o,'r /-WORD .byte 4,200+'l,'o,'r /-LORD .byte 4,200+'f,'o,'r /-FORD .byte 4,200+'y,'a,'r /-YARD .byte 4,200+'w,'a,'r /-WARD .byte 5,200+'g,'u,'a,'r /-GUARD .byte 4,200+'t,'a,'r /-TARD .byte 5,200+'b,'o,'a,'r /-BOARD .byte 4,200+'n,'a,'r /-NARD .byte 5,200+'l,'i,'a,'r /-LIARD .byte 4,200+'i,'a,'r /-IARD .byte 4,200+'g,'a,'r /-GARD .byte 4,200+'b,'a,'r /-BARD .byte 3,200+'r,'o /-ROD .byte 4,200+'w,'o,'o /-WOOD .byte 4,200+'h,'o,'o /-HOOD .byte 4,200+'m,'o,'n /-MOND .byte 4,200+'t,'e,'n /-TEND .byte 5,200+'s,'t,'a,'n /-STAND .byte 4,200+'l,'a,'n /-LAND .byte 4,200+'h,'a,'n /-HAND .byte 4,200+'h,'o,'l /-HOLD .byte 4,200+'f,'o,'l /-FOLD .byte 5,200+'f,'i,'e,'l /-FIELD .byte 3,200+'v,'i /-VID .byte 3,200+'c,'i /-CID .byte 4,200+'s,'a,'i /-SAID .byte 4,200+'m,'a,'i /-MAID .byte 4,'t,200+'t,'e /T-TED .byte 3,'t,200+'e /T-ED .byte 4,200+'d,'r,'e /-DRED .byte 4,200+'c,'r,'e /-CRED .byte 4,200+'b,'r,'e /-BRED .byte 5,'v,200+'e,'l,'e /V-ELED .byte 100+4,'a,'l,200+'e /AL/ED .byte 140+3,200+'e,'e //EED .byte 40+5,'e,'d,200+'d,'e /ED-DED .byte 4,'d,200+'d,'e /D-DED .byte 40+4,'e,'d,200+'e /ED-ED .byte 3,'d,200+'e /D-ED .byte 5,200+'d,'u,'c,'e /-DUCED .byte 300+2,'e /E/D .byte 5,200+'s,'t,'e,'a /-STEAD .byte 4,200+'h,'e,'a /-HEAD .byte 0 sufe: .byte 5,'a,'r,200+'i,'z /AR-IZE .byte 5,'a,'n,200+'i,'z /AN-IZE .byte 5,'a,'l,200+'i,'z /AL-IZE .byte 6,200+'a,'r,'d,200+'i,'z /-ARD-IZE .byte 5,200+'s,'e,'l,'v /-SELVE .byte 5,200+'k,'n,'i,'v /-KNIVE .byte 5,200+'l,'i,'e,'v /-LIEVE .byte 100+3,200+'q,'u //QUE .byte 7,'o,'n,200+'t,'i,'n,200+'u /ON-TIN-UE .byte 3,200+'n,'u /-NUE .byte 3,200+'d,'u /-DUE .byte 300+2,'u /U/E .byte 300+5,'q,'u,'a,'t / QUAT/E .byte 4,'u,200+'a,'t /U-ATE .byte 5,200+'s,'t,'a,'t /-STATE .byte 4,200+'t,'a,'t /-TATE .byte 6,200+'t,'o,'r,200+'a,'t /-TOR-ATE .byte 5,'e,'n,200+'a,'t /EN-ATE .byte 4,200+'m,'a,'t /-MATE .byte 5,200+'h,'o,'u,'s /-HOUSE .byte 5,200+'c,'l,'o,'s /-CLOSE .byte 4,'i,200+'o,'s /I-OSE .byte 4,200+'w,'i,'s /-WISE .byte 5,'a,'s,200+'u,'r /AS-URE .byte 40+4,200+'s,'u,'r /-SURE .byte 6,200+'f,'i,'g,200+'u,'r /-FIG-URE .byte 40+3,200+'t,'r /-TRE .byte 5,200+'s,'t,'o,'r /-STORE .byte 4,200+'f,'o,'r /-FORE .byte 5,200+'w,'h,'e,'r /-WHERE .byte 3,200+'d,'r /-DRE .byte 3,200+'c,'r /-CRE .byte 3,200+'b,'r /-BRE .byte 5,200+'s,'c,'o,'p /-SCOPE .byte 4,'y,200+'o,'n /Y-ONE .byte 5,200+'s,'t,'o,'n /-STONE .byte 5,200+'p,'h,'o,'n /-PHONE .byte 4,200+'g,'o,'n /-GONE .byte 4,'e,200+'o,'n /E-ONE .byte 40+4,200+'e,'n,'n /-ENNE .byte 40+5,'a,200+'r,'i,'n /A-RINE .byte 5,200+'c,'l,'i,'n /-CLINE .byte 4,200+'l,'i,'n /-LINE .byte 07,0200+'r,'o,'u,0200+'t,'i,'n /*-ROU-TINE*/ .byte 4,200+'s,'o,'m /-SOME .byte 4,200+'c,'o,'m /-COME .byte 4,200+'t,'i,'m /-TIME .byte 3,200+'z,'l /-ZLE .byte 3,200+'t,'l /-TLE .byte 3,200+'s,'l /-SLE .byte 3,200+'p,'l /-PLE .byte 5,200+'v,'i,'l,'l /-VILLE .byte 4,'c,'k,200+'l /CK-LE .byte 3,200+'k,'l /-KLE .byte 3,200+'g,'l /-GLE .byte 3,200+'f,'l /-FLE .byte 3,200+'d,'l /-DLE .byte 3,200+'c,'l /-CLE .byte 5,200+'p,'a,200+'b,'l /-PA-BLE .byte 5,'f,'a,200+'b,'l /FA-BLE .byte 5,200+'c,'a,200+'b,'l /-CA-BLE .byte 6,200+'s,'t,'a,'b,'l /-STABLE .byte 4,200+'a,'b,'l /-ABLE .byte 3,200+'b,'l /-BLE .byte 4,200+'d,'a,'l /-DALE .byte 4,200+'m,'a,'l /-MALE .byte 4,200+'s,'a,'l /-SALE .byte 4,200+'l,'i,'k /-LIKE .byte 340+5,'g,200+'u,'a,'g /-G/UAGE .byte 5,200+'r,'i,'a,'g /-RIAGE .byte 5,'e,'r,200+'a,'g /ER-AGE .byte 4,'m,200+'a,'g /M-AGE .byte 4,'k,200+'a,'g /K-AGE .byte 4,'d,200+'a,'g /D-AGE .byte 4,200+'w,'i,'f /-WIFE .byte 5,200+'k,'n,'i,'f /-KNYFE .byte 3,200+'s,'e /-SEE .byte 4,200+'f,'r,'e /-FREE .byte 340+2,'e /EE .byte 4,200+'w,'i,'d /-WIDE .byte 4,200+'t,'i,'d /-TIDE .byte 4,200+'s,'i,'d /-SIDE .byte 6,200+'q,'u,'e,'n,'c /-QUENCE .byte 7,200+'f,'l,'u,200+'e,'n,'c /-FLU-ENCE .byte 40+6,'e,'s,200+'e,'n,'c /ES-ENCE .byte 6,'e,'r,200+'e,'n,'c /ER-ENCE .byte 5,'i,200+'e,'n,'c /I-ENCE .byte 40+5,200+'s,'a,'n,'c /-SANCE .byte 6,'e,'r,200+'a,'n,'c /ER-ANCE .byte 6,'a,'r,200+'a,'n,'c /AR-ANCE .byte 5,200+'n,'a,'n,'c /-NANCE .byte 7,200+'b,'a,'l,200+'a,'n,'c /-BAL-ANCE .byte 5,'i,200+'a,'n,'c /I-ANCE .byte 7,200+'j,'u,'s,200+'t,'i,'c /-JUS-TICE .byte 5,200+'s,'t,'i,'c /-STICE .byte 5,200+'p,'i,'e,'c /-PIECE .byte 5,200+'p,'l,'a,'c /-PLACE .byte 340+1 //E .byte 0 suff: .byte 5,200+'p,'r,'o,'o /-PROOF .byte 4,200+'s,'e,'l /-SELF .byte 3,200+'r,'i /-RIF .byte 40+4,200+'l,'i,'e /-LIEF .byte 0 sufg: .byte 3,200+'l,'o /-LOG .byte 4,200+'l,'o,'n /-LONG .byte 5,'t,200+'t,'i,'n /T-TING .byte 6,200+'s,'t,'r,'i,'n / -STRING .byte 5,'r,200+'r,'i,'n /R-RING .byte 5,'p,200+'p,'i,'n /P-PING .byte 5,'n,200+'n,'i,'n /N-NING .byte 5,'m,200+'m,'i,'n /M-MING .byte 5,'l,200+'l,'i,'n / L-LING .byte 5,200+'z,'l,'i,'n /-ZLING .byte 5,200+'t,'l,'i,'n /-TLING .byte 40+5,'s,200+'l,'i,'n /S-LING .byte 5,'r,200+'l,'i,'n /R-LING .byte 5,200+'p,'l,'i,'n /-PLING .byte 6,'n,200+'k,'l,'i,'n /N-KLING .byte 5,'k,200+'l,'i,'n /K-LING .byte 5,200+'g,'l,'i,'n /-GLING .byte 5,200+'f,'l,'i,'n /-FLING .byte 5,200+'d,'l,'i,'n /-DLING .byte 5,200+'c,'l,'i,'n /-CLING .byte 5,200+'b,'l,'i,'n /-BLING .byte 6,'y,200+'t,'h,'i,'n /Y-THING .byte 7,'e,'e,'t,'h,200+'i,'n /EETH-ING .byte 6,'e,200+'t,'h,'i,'n /E-THING .byte 5,'g,200+'g,'i,'n /G-GING .byte 5,'d,200+'d,'i,'n /D-DING .byte 5,'b,200+'b,'i,'n /B-BING .byte 3,200+'i,'n /-ING .byte 0 sufh: .byte 5,200+'m,'o,'u,'t /-MOUTH .byte 5,200+'w,'o,'r,'t /-WORTH .byte 4,200+'w,'i,'t /-WITH .byte 5,'t,200+'t,'i,'s /T-TISH .byte 5,'e,200+'t,'i,'s /E-TISH .byte 5,'p,200+'p,'i,'s /P-PISH .byte 5,'r,200+'n,'i,'s /R-NISH .byte 5,'n,200+'n,'i,'s /N-NISH .byte 5,200+'p,'l,'i,'s /-PLISH .byte 5,200+'g,'u,'i,'s / -GUISH .byte 5,200+'g,'l,'i,'s / -GLISH .byte 5,'b,200+'l,'i,'s / B-LISH .byte 5,'g,200+'g,'i,'s /G-GISH .byte 5,'d,200+'d,'i,'s /D-DISH .byte 3,200+'i,'s /-ISH .byte 5,200+'g,'r,'a,'p /-GRAPH .byte 7,200+'b,'o,'r,200+'o,'u,'g /-BOR-OUGH .byte 5,200+'b,'u,'r,'g /-BURGH .byte 4,200+'v,'i,'c /-VICH .byte 3,200+'n,'a /-NAH .byte 3,200+'l,'a /-LAH .byte 4,200+'m,'i,200+'a /-MI-AH .byte 0 sufi: .byte 3,200+'t,'r /-TRI .byte 3,200+'c,'h /-CHI .byte 200+3,'i,'f /IF-I .byte 200+3,'e,'d /ED-I .byte 5,200+'a,'s,'c,'i /-ASCII .byte 0 sufk: .byte 4,200+'w,'o,'r /-WORK .byte 4,200+'m,'a,'r /-MARK .byte 4,200+'b,'o,'o /-BOOK .byte 4,200+'w,'a,'l /-WALK .byte 5,200+'c,'r,'a,'c /-CRACK .byte 4,200+'b,'a,'c /-BACK .byte 0 sufl: .byte 3,200+'f,'u /-FUL .byte 5,'s,200+'w,'e,'l /S-WELL .byte 4,200+'t,'e,'l /-TELL .byte 5,200+'s,'h,'e,'l /-SHELL .byte 5,200+'s,'t,'a,'l /-STALL .byte 4,200+'s,'t,'a /-STAL .byte 4,200+'b,'a,'l /-BALL .byte 3,'v,200+'e /V-EL .byte 3,'u,200+'e /U-EL .byte 3,'k,200+'e /K-EL .byte 4,'t,'h,200+'e /TH-EL .byte 5,'t,'c,'h,200+'e /TCH-EL .byte 3,'a,200+'e /A-EL .byte 140+4,200+'q,'u,'a //QUAL .byte 40+3,'u,200+'a /U-AL .byte 3,200+'t,'a /-TAL .byte 4,'u,'r,200+'a /UR-AL .byte 40+5,'g,200+'o,200+'n,'a /G-O-NAL .byte 4,'o,'n,200+'a /ON-AL .byte 3,200+'n,'a /-NAL .byte 4,200+'t,'i,'a /-TIAL .byte 4,200+'s,'i,'a /-SIAL .byte 40+5,200+'t,'r,'i,200+'a /-TRI-AL .byte 4,'r,'i,200+'a /RI-AL .byte 4,200+'n,'i,200+'a /-NI-AL .byte 4,200+'d,'i,200+'a /-DI-AL .byte 4,200+'c,'i,'a /-CIAL .byte 3,200+'g,'a /-GAL .byte 4,200+'m,'e,'a /-MEAL /.byte 40+4,200+'r,'e,200+'a /-RE-AL .byte 40+4,200+'r,'e,'a /-REAL .byte 6,'c,200+'t,'i,200+'c,'a /C-TI-CAL .byte 5,200+'s,'i,200+'c,'a /-SI-CAL .byte 4,200+'i,200+'c,'a /-I-CAL .byte 3,200+'c,'a /-CAL .byte 3,200+'b,'a /-BAL .byte 6,200+'n,'o,200+'m,'i,200+'a /-NO-MI-AL .byte 0 sufm: .byte 3,200+'n,'u /-NUM .byte 5,'o,200+'r,'i,200+'u /O-RI-UM .byte 40+3,'i,200+'u /I-UM .byte 40+3,'e,200+'u /E-UM .byte 5,'i,'v,200+'i,'s /IV-ISM .byte 4,200+'t,'i,'s /-TISM .byte 5,'i,200+'m,'i,'s /I-MISM .byte 5,'a,'l,200+'i,'s /AL-ISM .byte 40+4,'e,200+'i,'s /E-ISM .byte 40+4,'a,200+'i,'s /A-ISM .byte 4,200+'r,'o,'o /-ROOM .byte 3,200+'d,'o /-DOM .byte 3,200+'h,'a /-HAM .byte 6,200+'a,200+'r,'i,'t,'h /-A-RITHM .byte 5,200+'r,'i,'t,'h /-RITHM .byte 0 sufn: .byte 4,200+'t,'o,'w /-TOWN .byte 4,200+'d,'o,'w /-DOWN .byte 4,200+'t,'u,'r /-TURN .byte 5,200+'s,'p,'o,'o /-SPOON .byte 4,200+'n,'o,'o /-NOON .byte 4,200+'m,'o,'o /-MOON .byte 11,'a,'l,200+'i,200+'z,'a,200+'t,'i,'o /AL-I-ZA-TION .byte 7,200+'i,200+'z,'a,200+'t,'i,'o /-I-ZA-TION .byte 7,'l,200+'i,200+'a,200+'t,'i,'o /L-I-A-TION .byte 4,200+'t,'i,'o /-TION .byte 40+5,'s,200+'s,'i,'o /S-SION .byte 4,200+'s,'i,'o /-SION .byte 4,'n,200+'i,'o /N-ION .byte 4,200+'g,'i,'o /-GION .byte 4,200+'c,'i,'o /-CION .byte 3,200+'c,'o /-CON .byte 3,200+'t,'o /-TON .byte 3,200+'s,'o /-SON .byte 3,200+'r,'i /-RIN .byte 3,200+'p,'i /-PIN .byte 3,200+'n,'i /-NIN .byte 3,200+'m,'i /-MIN .byte 3,200+'l,'i /-LIN .byte 3,200+'k,'i /-KIN .byte 5,200+'s,'t,'e,'i /-STEIN .byte 4,200+'t,'a,'i /-TAIN .byte 5,'g,'h,'t,200+'e /GHT-EN .byte 5,200+'w,'o,'m,200+'e /-WOM-EN .byte 3,200+'m,'e /-MEN .byte 4,'o,200+'k,'e /O-KEN .byte 3,'k,200+'e /K-EN .byte 4,200+'t,'e,'e /-TEEN .byte 4,200+'s,'e,'e /-SEEN .byte 40+3,200+'s,'a /-SAN .byte 5,200+'w,'o,'m,200+'a /-WOM-AN .byte 3,200+'m,'a /-MAN .byte 4,200+'t,'i,'a /-TIAN .byte 4,200+'s,'i,'a /-SIAN .byte 40+4,'e,200+'i,'a /E-IAN .byte 4,200+'c,'i,'a /-CIAN .byte 300+3,'i,'a /IA/N .byte 5,200+'c,'l,'e,'a /-CLEAN .byte 4,200+'m,'e,'a /-MEAN .byte 40+3,'e,200+'a /E-AN .byte 0 sufo: .byte 5,200+'m,'a,'c,200+'r /-MAC-RO .byte 0 sufp: .byte 5,200+'g,'r,'o,'u /-GROUP .byte 2,200+'u /-UP .byte 4,200+'s,'h,'i /-SHIP .byte 4,200+'k,'e,'e /-KEEP .byte 0 sufr: .byte 4,200+'z,'a,'r /-ZARR .byte 300+2,'r /R/R .byte 3,200+'t,'o /-TOR .byte 40+3,200+'s,'o /-SOR .byte 40+4,200+'r,'i,200+'o /-RI-OR .byte 4,'i,'z,200+'e /IZ-ER .byte 5,200+'c,'o,'v,200+'e /-COV-ER /.byte 4,'o,200+'v,'e /O-VER .byte 4,200+'o,'v,'e /-OVER .byte 4,200+'e,'v,200+'e /-EV-ER .byte 8.,200+'c,'o,'m,200+'p,'u,'t,200+'e /-COM-PUT-ER .byte 40+5,'u,'s,200+'t,'e /US-TER .byte 5,'o,'s,'t,200+'e /OST-ER .byte 40+5,200+'a,'c,200+'t,'e /-AC-TER .byte 6,200+'w,'r,'i,'t,200+'e /-WRIT-ER .byte 40+5,'i,'s,200+'t,'e /IS-TER .byte 40+5,'e,'s,200+'t,'e /ES-TER .byte 40+5,'a,'s,200+'t,'e /AS-TER .byte 4,200+'s,'t,'e /-STER .byte 5,'a,'r,200+'t,'e /AR-TER .byte 4,'r,'t,200+'e /RT-ER .byte 40+5,'m,200+'e,200+'t,'e /M-E-TER .byte 5,200+'w,'a,200+'t,'e /-WA-TER .byte 3,'r,200+'e /R-ER .byte 4,'o,'p,200+'e /OP-ER .byte 5,200+'p,'a,200+'p,'e /-PA-PER .byte 4,'w,'n,200+'e /WN-ER .byte 40+4,'s,200+'n,'e /S-NER .byte 4,'o,'n,200+'e /ON-ER .byte 4,'r,'m,200+'e /RM-ER .byte 3,200+'m,'e /-MER .byte 4,'l,'l,200+'e /LL-ER .byte 5,'d,200+'d,'l,'e /D-DLER .byte 4,200+'b,'l,'e /-BLER .byte 3,'k,200+'e /K-ER .byte 5,'n,200+'t,'h,'e /N-THER .byte 6,200+'f,'a,200+'t,'h,'e /-FA-THER .byte 6,'e,'i,200+'t,'h,'e /EI-THER .byte 4,'t,'h,200+'e /TH-ER .byte 4,'s,'h,200+'e /SH-ER .byte 4,200+'p,'h,'e /-PHER .byte 4,'c,'h,200+'e /CH-ER .byte 4,'d,'g,200+'e /DG-ER .byte 4,'r,'d,200+'e /RD-ER .byte 6,'o,'u,'n,'d,200+'e /OUND-ER .byte 4,'l,'d,200+'e /LD-ER .byte 4,'i,'d,200+'e /ID-ER .byte 5,200+'d,'u,'c,200+'e /-DUC-ER .byte 4,'n,'c,200+'e /NC-ER .byte 100+2, 200+'e / /ER .byte 3,200+'s,'a /-SAR .byte 40+6,'a,'c,200+'u,200+'l,'a /AC-U-LAR .byte 40+6,'e,'c,200+'u,200+'l,'a /EC-U-LAR .byte 40+6,'i,'c,200+'u,200+'l,'a /IC-U-LAR .byte 40+6,'e,'g,200+'u,200+'l,'a /EG-U-LAR .byte 0 sufs: .byte 40+4,'u,200+'o,'u /U-OUS .byte 5,200+'t,'i,'o,'u /-TIOUS .byte 5,200+'g,'i,'o,'u /-GIOUS .byte 5,200+'c,'i,'o,'u /-CIOUS .byte 40+4,'i,200+'o,'u /I-OUS .byte 5,200+'g,'e,'o,'u /-GEOUS .byte 5,200+'c,'e,'o,'u /-CEOUS .byte 4,'e,200+'o,'u /E-OUS .byte 140+2,200+'u //US .byte 4,200+'n,'e,'s /-NESS .byte 4,200+'l,'e,'s /-LESS .byte 140+2,200+'s //SS .byte 40+5,'p,200+'o,200+'l,'i /P-O-LIS .byte 140+2,200+'i //IS .byte 100+3,200+'x,'e /X/ES .byte 100+3,200+'s,'e /S/ES .byte 100+4,'s,'h,200+'e /SH/ES .byte 100+4,'c,'h,200+'e /CH/ES .byte 300+1 //S .byte 0 suft: .byte 6,'i,'o,'n,200+'i,'s /ION-IST .byte 5,'i,'n,200+'i,'s /IN-IST .byte 5,'a,'l,200+'i,'s /AL-IST .byte 6,'l,200+'o,200+'g,'i,'s /L-O-GIST .byte 5,'h,'t,200+'e,'s /HT-EST .byte 4,'i,200+'e,'s /I-EST .byte 5,'g,200+'g,'e,'s /G-GEST .byte 4,'g,200+'e,'s /G-EST .byte 5,'d,200+'d,'e,'s /D-DEST .byte 4,'d,200+'e,'s /D-EST .byte 4,200+'c,'a,'s /-CAST .byte 5,200+'h,'e,'a,'r /-HEART .byte 4,200+'f,'o,'o /-FOOT .byte 3,'i,200+'o /I-OT .byte 5,200+'f,'r,'o,'n /-FRONT .byte 5,200+'p,'r,'i,'n /-PRINT .byte 4,200+'m,'e,'n /-MENT .byte 5,200+'c,'i,'e,'n /-CIENT .byte 4,'i,200+'a,'n /I-ANT .byte 6,200+'w,'r,'i,'g,'h /-WRIGHT .byte 6,200+'b,'r,'i,'g,'h /-BRIGHT .byte 6,200+'f,'l,'i,'g,'h /-FLIGHT .byte 6,200+'w,'e,'i,'g,'h /-WEIGHT .byte 5,200+'s,'h,'i,'f /-SHIFT .byte 5,200+'c,'r,'a,'f /-CRAFT .byte 40+4,'d,'g,200+'e /DG-ET .byte 4,200+'g,'o,'a /-GOAT .byte 4,200+'c,'o,'a /-COAT .byte 4,200+'b,'o,'a /-BOAT .byte 4,200+'w,'h,'a /-WHAT .byte 4,200+'c,'u,'i /-CUIT .byte 0 sufy: .byte 40+4,'e,'s,200+'t /ES-TY .byte 40+5,'q,'u,'i,200+'t /QUI-TY .byte 4,200+'t,'i,200+'t /-TI-TY .byte 40+5,'o,'s,200+'i,200+'t /OS-I-TY .byte 4,200+'s,'i,200+'t /-SI-TY .byte 5,'i,'n,200+'i,200+'t /IN-I-TY .byte 4,'n,'i,200+'t /NI-TY .byte 40+10,'f,'a,200+'b,'i,'l,200+'i,200+'t /FA-BIL-I-TY .byte 10,200+'c,'a,200+'b,'i,'l,200+'i,200+'t /-CA-BIL-I-TY .byte 10,200+'p,'a,200+'b,'i,'l,200+'i,200+'t /-PA-BIL-I-TY .byte 6,200+'b,'i,'l,200+'i,200+'t /-BIL-I-TY .byte 3,'i,200+'t /I-TY .byte 4,200+'b,'u,'r /-BUR-Y .byte 4,200+'t,'o,200+'r /-TO-RY .byte 5,200+'q,'u,'a,'r /-QUAR-Y .byte 40+4,'u,200+'a,'r /U-ARY .byte 7,200+'m,'e,'n,200+'t,'a,200+'r /-MEN-TA-RY .byte 6,'i,'o,'n,200+'a,'r /ION-ARY .byte 4,'i,200+'a,'r /I-ARY .byte 4,'n,200+'o,200+'m /N-O-MY .byte 3,200+'p,'l /-PLY .byte 4,'g,200+'g,'l /G-GLY .byte 5,200+'p,'a,200+'b,'l /-PA-BLY .byte 5,'f,'a,200+'b,'l /FA-BLY .byte 5,200+'c,'a,200+'b,'l /-CA-BLY .byte 4,200+'a,'b,'l /-ABLY .byte 3,200+'b,'l /-BLY .byte 2,200+'l /-LY .byte 3,200+'s,'k /-SKY .byte 40+6,'g,200+'r,'a,200+'p,'h /G-RA-PHY .byte 4,'l,200+'o,200+'g /L-O-GY .byte 2,200+'f /-FY .byte 3,200+'n,'e /-NEY .byte 3,200+'l,'e /-LEY .byte 4,'c,'k,200+'e /CK-EY .byte 3,200+'k,'e /-KEY .byte 4,200+'b,'o,'d /-BODY .byte 5,200+'s,'t,'u,'d /-STUDY .byte 340+4,'e,'e,'d /EEDY .byte 2,200+'b /-BY .byte 3,200+'w,'a /-WAY .byte 3,200+'d,'a /-DAY .byte 0 .even b,'l /FA-BLY .byte 5,200+'c,'a,200+'b,'l /-CA-BLY .byte 4,200+'a,'b,'l /-ABLY .byte 3,200+'b,'l /-BLY .byte 2,200+'l /-LY .byte 3,200+'s,'k /-SKY .byte 40+6,'g,200+'r,'a,200+'p,'h /G-RA-PHY .byte 4,'l,200+'o,200+'g /L-O-GY .byte 2,200+'f /-FY .byte 3,200+'n,'e /-NEY .byte 3,200+'l,'e /-LEY .byte 4,'c,'k,200+'e /CK-EY .byte 3,200+'k,'e /-KEY .byte 4,200+'b,'o,'d /-BODY .byte 5,200+'s,'t,'u,'d /-STUDY .byte 340+4,'e,'/ hyphenation digram tables .globl _bxh .globl _hxx .globl _bxxh .globl _xhx .globl _xxh _bxh: .byte 060,000,040,000,040,000,000,040,000,000,040,000,040 .even _hxx: .byte 006,042,041,123,021,024,063,042,002,043,021,001,022 .byte 140,000,200,003,260,006,000,160,007,000,140,000,320 .byte 220,000,160,005,240,010,000,100,006,000,200,000,320 .byte 240,000,120,003,140,000,000,240,010,000,220,000,160 .byte 042,023,041,040,040,022,043,041,030,064,021,000,041 .byte 100,000,140,000,220,006,000,140,003,000,200,000,000 .byte 200,000,120,002,220,010,000,160,006,000,140,000,320 .byte 020,000,020,000,020,000,000,020,000,000,020,000,000 .byte 043,163,065,044,022,043,104,042,061,146,061,000,007 .byte 100,000,140,000,040,000,000,100,000,000,120,000,000 .byte 140,000,040,011,060,004,001,120,003,000,140,000,040 .byte 200,000,100,000,140,000,000,140,000,000,140,000,240 .byte 200,000,140,000,160,000,000,220,000,000,140,000,240 .byte 200,000,140,000,160,000,000,220,000,000,060,000,240 .byte 021,043,041,121,040,023,042,003,142,042,061,001,022 .byte 120,000,140,010,140,010,000,140,002,000,120,000,120 .byte 000,000,000,000,360,000,000,000,000,000,160,000,000 .byte 100,000,040,005,120,000,000,100,000,000,060,000,140 .byte 140,040,100,001,240,041,000,242,000,002,140,000,100 .byte 240,000,120,002,200,000,000,320,007,000,240,000,340 .byte 101,021,041,020,040,005,042,121,002,021,201,000,020 .byte 160,000,100,000,140,000,000,160,006,000,220,000,140 .byte 140,000,020,001,020,000,000,100,001,000,300,000,000 .byte 000,000,000,000,000,000,000,000,000,000,000,000,000 .byte 106,041,040,147,040,000,063,041,001,102,160,002,002 .byte 300,000,040,017,140,017,000,240,000,000,140,000,120 _bxxh: .byte 005,150,153,062,062,246,152,127,146,203,310,017,206 .byte 100,000,120,000,140,000,000,100,000,000,120,000,060 .byte 100,000,040,000,060,000,000,060,000,000,220,000,040 .byte 100,000,120,000,200,000,000,100,000,000,140,000,060 .byte 043,142,046,140,062,147,210,131,046,106,246,017,111 .byte 060,000,020,000,060,000,000,040,000,000,100,000,000 .byte 060,000,040,000,040,000,000,040,000,000,100,000,040 .byte 100,000,100,000,100,000,000,040,000,000,100,000,140 .byte 066,045,145,140,000,070,377,030,130,103,003,017,006 .byte 040,000,040,000,020,000,000,040,000,000,100,000,000 .byte 200,000,020,000,140,000,000,120,000,000,120,000,040 .byte 120,000,040,000,060,000,000,060,000,000,160,000,040 .byte 120,000,040,000,120,000,000,040,000,000,160,000,040 .byte 120,000,020,000,140,000,000,120,000,000,140,000,040 .byte 051,126,150,140,060,210,146,006,006,165,003,017,244 .byte 120,000,040,000,160,000,000,140,000,000,060,000,140 .byte 000,000,000,000,000,000,000,000,000,000,000,000,000 .byte 140,000,140,000,060,000,000,100,000,000,140,000,020 .byte 120,000,020,000,060,000,000,060,000,000,060,000,040 .byte 140,000,020,000,100,000,000,140,000,000,140,000,020 .byte 070,125,051,162,120,105,126,104,006,044,000,017,052 .byte 140,000,020,000,140,000,000,060,000,000,060,000,040 .byte 020,000,000,000,020,000,000,000,000,000,000,000,060 .byte 140,000,160,000,200,000,000,140,000,000,000,000,240 .byte 065,042,060,200,000,210,222,146,006,204,220,012,003 .byte 240,000,020,000,120,000,000,200,000,000,200,000,240 _xhx: .byte 032,146,042,107,076,102,042,146,202,050,006,000,051 .byte 036,377,057,013,057,366,377,057,001,377,057,000,040 .byte 037,377,020,000,100,022,377,057,362,116,100,000,017 .byte 057,377,057,031,137,363,377,037,362,270,077,000,117 .byte 074,142,012,236,076,125,063,165,341,046,047,000,024 .byte 020,017,075,377,040,001,377,017,001,204,020,000,040 .byte 057,017,057,340,140,362,314,117,003,302,100,000,057 .byte 057,357,077,017,100,366,314,057,342,346,037,000,060 .byte 252,145,072,157,377,165,063,066,164,050,363,000,362 .byte 000,000,020,000,020,000,000,017,000,000,020,000,000 .byte 117,017,237,377,200,354,125,110,004,257,000,000,300 .byte 057,367,054,357,157,216,314,114,217,353,053,000,057 .byte 077,213,077,077,177,317,377,114,377,352,077,000,076 .byte 077,213,077,077,157,177,377,054,377,352,117,000,075 .byte 125,230,065,216,057,066,063,047,345,126,011,000,033 .byte 057,377,051,360,120,361,273,056,001,256,057,000,060 .byte 000,000,000,000,000,000,000,000,000,000,000,000,000 .byte 076,310,056,310,137,174,273,055,335,266,033,000,155 .byte 077,157,057,360,057,063,042,024,077,206,020,000,040 .byte 057,037,077,360,100,365,377,037,362,176,050,000,026 .byte 167,146,042,112,077,110,062,254,366,052,377,000,163 .byte 060,000,040,000,120,000,377,060,012,000,037,000,257 .byte 037,232,157,361,040,003,125,010,001,256,000,000,340 .byte 377,377,377,377,377,377,377,377,377,377,377,017,277 .byte 253,315,257,216,377,206,146,306,371,126,232,000,004 .byte 057,012,100,360,160,360,000,040,000,017,157,000,176 _xxh: .byte 045,150,154,162,042,246,210,147,152,103,230,017,206 .byte 100,000,040,000,140,000,000,100,000,021,120,017,060 .byte 100,000,040,002,140,320,000,060,000,001,220,017,040 .byte 100,001,120,001,241,000,000,100,000,020,140,017,060 .byte 023,162,046,142,022,207,210,131,052,106,250,017,110 .byte 060,000,042,000,160,000,000,040,000,212,100,017,000 .byte 140,000,040,002,140,000,000,120,000,040,120,017,040 .byte 100,000,100,000,140,001,021,140,000,046,100,017,140 .byte 066,045,025,201,020,130,146,030,130,103,025,017,006 .byte 100,000,040,000,020,000,000,040,000,000,200,017,000 .byte 200,000,020,001,140,000,000,140,000,000,120,017,040 .byte 120,026,042,020,140,161,042,143,000,022,162,017,040 .byte 121,042,060,020,140,200,000,123,000,021,220,017,041 .byte 121,042,060,120,140,200,000,123,000,021,160,017,041 .byte 051,126,150,141,060,210,146,066,026,165,026,017,247 .byte 120,000,040,003,160,000,000,140,000,021,100,017,140 .byte 000,000,000,000,200,000,000,000,000,000,000,017,000 .byte 141,023,122,040,160,143,042,142,000,047,143,017,020 .byte 120,000,040,006,140,060,000,141,000,026,100,017,040 .byte 140,000,020,007,100,000,000,140,000,001,140,017,020 .byte 110,125,051,162,120,125,127,104,006,104,000,017,052 .byte 140,000,040,000,160,000,000,140,000,000,060,017,000 .byte 040,005,020,000,040,313,231,030,000,140,000,017,056 .byte 140,000,160,000,200,000,000,140,000,000,000,017,240 .byte 065,042,060,040,000,206,231,146,006,224,220,017,004 .byte 240,000,020,000,140,000,000,220,000,000,200,017,141 .even ,040,160,143,042,142,000,047,143,017,020 .byte 120,000,040,006,140,060,000,141,000,026,100,017,040 .byte 140,000,020,007,100,000,000,140,000,001,140,017,020 .byte 110,125,051,162,120,125,127,104,006,104,000,017,052 .byte 140,000,040,000,160,000,000,140,000,000,060,017,000 .byte 040,005,020,000,040,313,231,030,000,140,000,017,056 .byte 140,000,160,000,200,000,000,140,000,000,000,017,240 .byte 065,042,060,040,000,206,231,146,#include "tdef.h" #include "t.h" #include "tw.h" /* troff1.c consume options, initialization, main loop, input routines, escape function calling */ extern int stdi; extern int waitf; extern int nofeed; extern int quiet; extern int ptid; extern int ascii; extern int npn; extern int xflg; extern int stop; extern char ibuf[IBUFSZ]; extern char xbuf[IBUFSZ]; extern char *ibufp; extern char *xbufp; extern char *eibuf; extern char *xeibuf; extern int cbuf[NC]; extern int *cp; extern int *vlist; extern int nx; extern int mflg; extern int ch; extern int pto; extern int pfrom; extern int cps; extern int chbits; extern int suffid; extern int sufind[26]; extern char suftab[]; extern int ibf; extern int ttyod; extern int ttys[3]; extern int iflg; extern int ioff; extern int init; extern int rargc; extern char **argp; extern char trtab[256]; extern int lgf; extern int copyf; extern int eschar; extern int ch0; extern int cwidth; extern int ip; extern int nlflg; extern int *nxf; extern int *ap; extern int *frame; extern int *stk; extern int donef; extern int nflush; extern int nchar; extern int rchar; extern int nfo; extern int ifile; extern int fc; extern int padc; extern int tabc; extern int dotc; extern int raw; extern int tabtab[NTAB]; extern int iline; extern char nextf[]; extern int nfi; #ifdef NROFF extern char termtab[]; extern int tti; #endif extern int ifl[NSO]; extern int offl[NSO]; extern int ifi; extern int pendt; extern int flss; extern int fi; extern int lg; extern char ptname[]; extern int print; extern int nonumb; extern int pnlist[]; extern int *pnp; extern int nb; extern int trap; extern int *litlev; extern int tflg; extern int ejf; extern int *ejl; extern int lit; extern int cc; extern int c2; extern int spread; extern int gflag; extern int oline[]; extern int *olinep; extern int dpn; extern int noscale; extern char *unlkp; extern int pts; extern int level; extern int ttysave; extern int tdelim; extern int dotT; extern int tabch, ldrch; extern int eqflg; extern int xxx; char lnx[] "/dev/lnxx"; extern struct contab { int rq; int (*f)(); }contab[NM]; int ms[] {31,28,31,30,31,30,31,31,30,31,30,31}; main(argc,argv) int argc; char **argv; { char *p, *q; int *cframe; register i, j; extern catch(), fpecatch(), kcatch(); signal(SIGHUP,catch); if(signal(SIGINT,catch) & 01){ signal(SIGHUP,1); signal(SIGINT,1); signal(SIGQUIT,1); } signal(SIGFPE,fpecatch); signal(SIGPIPE,catch); signal(SIGKILL,kcatch); init1(argv[0][0]); options: while(--argc > 0 && (++argv)[0][0]=='-') switch(argv[0][1]){ case 0: goto start; case 'i': stdi++; continue; case 'q': quiet++; continue; case 'n': npn = cnum(&argv[0][2]); continue; case 'p': xflg = 0; cps = cnum(&argv[0][2]); continue; case 's': if(!(stop = cnum(&argv[0][2])))stop++; continue; case 'r': vlist[findr(argv[0][2])] = cnum(&argv[0][3]); continue; case 'm': p = &nextf[nfi]; q = &argv[0][2]; while((*p++ = *q++) != 0); mflg++; continue; case 'o': getpn(&argv[0][2]); continue; #ifdef NROFF case 'e': eqflg++; continue; case 'T': p = &termtab[tti]; q = &argv[0][2]; if(!((*q) & 0177))continue; while((*p++ = *q++) != 0); dotT++; continue; #endif #ifndef NROFF case 'a': ascii = 1; nofeed++; case 't': ptid = 1; continue; case 'w': waitf = 1; continue; case 'f': nofeed++; continue; case 'x': xflg = 0; continue; case 'b': if(open(ptname,1) < 0)prstr("Busy.\n"); else prstr("Available.\n"); done3(0); case 'g': stop = ptid = gflag = 1; dpn = 0; continue; #endif default: pto = cnum(&argv[0][1]); continue; } if(argv[0][0] == '+'){ pfrom = cnum(&argv[0][1]); print = 0; if(argc > 0)goto options; } start: argp = argv; rargc = argc; init2(); setexit(); loop: copyf = lgf = nb = nflush = nlflg = 0; cframe = frame; i = getch(); if((frame != cframe) && ejf && (frame <= ejl)){ nflush++; trap = 0; ch = i; eject(0); goto loop; } if(pendt)goto lt; if(lit && (frame <= litlev)){ lit--; goto lt; } if((j = (i & CMASK)) == XPAR){ copyf++; tflg++; for(;(i & CMASK) != '\n';)pchar(i = getch()); tflg = 0; copyf--; goto loop; } if((j == cc) || (j == c2)){ if(j == c2)nb++; copyf++; while(((j=((i=getch()) & CMASK)) == ' ') || (j == '\t')); ch = i; copyf--; control(getrq(),1); flushi(); goto loop; } lt: ch = i; text(); goto loop; } catch(){ /* prstr("Interrupt\n"); */ done3(01); } fpecatch(){ prstrfl("Floating Exception.\n"); signal(SIGFPE,fpecatch); } kcatch(){ signal(SIGKILL,1); done3(01); } init1(a) char a; { register char *p; register i; extern int block; if((suffid=open(suftab,0)) < 0){ prstr("Cannot open suftab.\n"); exit(-1); } seek(suffid,16,0); read(suffid,sufind,2*26); p = mktemp("/usr/tmp/taXXXXX"); if(a == 'a')p = &p[5]; if((close(creat(p, 0600))) < 0){ prstr("Cannot create temp file.\n"); exit(-1); } ibf = open(p, 2); for(i=256; --i;)trtab[i]=i; trtab[UNPAD] = ' '; mchbits(); for(i=NEV; i--;)write(ibf, &block, EVS*2); if(a != 'a')unlkp = p; } init2() { register i,j; int k; struct{ char lobyte; char hibyte; }; ttyod = 2; k = lnxx(j=0); if(k.lobyte == 'x' && k.hibyte == 'x'){ k = lnxx(j=1); if(k.lobyte == 'x' && k.hibyte == 'x') k = lnxx(j=2); } lnx[7] = k.lobyte;lnx[8] = k.hibyte; if(j==0)iflg++; gtty(j,ttys); ttysave = ttys[2]; if(ascii)mesg(0); if((!ptid) && (!waitf)){ if((ptid = open(ptname,1)) < 0){ prstr("Typesetter busy.\n"); done3(-2); } } ptinit(); olinep = oline; ibufp = eibuf = ibuf; v.hp = ioff = init = 0; v.nl = -1; cvtime(); frame = stk = setbrk(DELTA); nxf = frame + STKSIZE; nx = mflg; } cvtime(){ int tt[2]; register i; time(tt); sub1(tt,3600*ZONE); /*5hrs for EST*/ v.dy = ldiv(tt[0],tt[1],60*60*8)/3 + 1; v.dw = (v.dy + 3)%7 + 1; for(v.yr=70;; v.yr++){ if((v.yr)%4)ms[1]=28;else ms[1]=29; for(i=0;i<12;){ if(v.dy<=ms[i]){ v.mo = i+1; return; } v.dy =- ms[i++]; } } } cnum(a) char *a; { register i; ibufp = a; eibuf = -1; i = atoi(); ch = 0; return(i); } mesg(f) int f; { static int mode; if(!f){ stat(lnx,cbuf); mode = cbuf[2]; chmod(lnx,mode & ~022); }else{ chmod(lnx,mode); } } prstrfl(s) char *s; { flusho(); prstr(s); } prstr(s) char *s; { register i; for(i=0;*s;i++)s++; write(ttyod,s-i,i); } control(a,b) int a,b; { register i,j; i = a; if((i == 0) || ((j = findmn(i)) == -1))return(0); if(contab[j].rq & MMASK){ *nxf = 0; if(b)collect(); flushi(); return(pushi(contab[j].f)); }else{ if(!b)return(0); return((*contab[j].f)(0)); } } getrq(){ register i,j; if(((i=getach()) == 0) || ((j=getach()) == 0))goto rtn; i =| (j<= eibuf) && (ibufp != -1))){ if(nfo)goto g1; g0: if(nextfile() && (ibufp < eibuf))goto g2; g1: nx = 0; if((j=read(ifile,ibuf,IBUFSZ)) <= 0)goto g0; ibufp = ibuf; eibuf = ibuf + j; } g2: i = *ibufp++ & 0177; ioff++; if(i >= 040)goto g4; else i = ifilt[i]; } if(raw)return(i); if((j = i & CMASK) == IMP)goto again; g3: if((i == 0) && !init)goto again; g4: if((copyf == 0) && ((i & ~BMASK) == 0) && ((i & CMASK) < 0370)) i =| chbits; if((i & CMASK) == eschar)i = (i & ~CMASK) | ESC; return(i); } nextfile(){ register char *p; n0: if(ifile)close(ifile); if(nx){ p = nextf; if(*p != 0)goto n1; } if(ifi > 0){ if(popf())goto n0; /*popf error*/ return(1); /*popf ok*/ } if(rargc-- <= 0)goto n2; p = (argp++)[0]; n1: if((p[0] == '-') && (p[1] == 0)){ ifile = 0; }else if((ifile=open(p,0)) < 0){ prstr("Cannot open "); prstr(p); prstr("\n"); nfo =- mflg; done(02); } nfo++; ioff = iline = 0; return(0); n2: if((nfo =- mflg) && !stdi)done(0); nfo++; iline = ioff = ifile = stdi = mflg = 0; return(0); } popf(){ register i, *p, *q; int k; struct{ char lobyte; char hibyte; }; ioff = offl[--ifi]; if((ifile = ifl[ifi]) == 0){ p = xbuf; q = ibuf; ibufp = xbufp; eibuf = xeibuf; while(q < eibuf)*q++ = *p++; return(0); } if((seek(ifile,ioff & ~CMASK,0) < 0) || ((i = read(ifile,ibuf,IBUFSZ)) < 0))return(1); eibuf = ibuf + i; ibufp = ibuf; k = lnxx(ifile); if(k.lobyte == 'x' && k.hibyte == 'x') if((ibufp = ibuf + (ioff & CMASK)) >= eibuf)return(1); return(0); } flushi(){ if(nflush)return; ch = 0; if((ch0 & CMASK) == '\n')nlflg++; ch0 = 0; copyf++; while(!nlflg){ if(donef && (frame == stk))break; getch(); } copyf--; v.hp = 0; } getach(){ register i; lgf++; if(((i = getch()) & MOT) || ((i&CMASK) == ' ') || ((i&CMASK) == '\n')|| (i & 0200)){ ch = i; i = 0; } lgf--; return(i & 0177); } casenx(){ lgf++; skip(); getname(); nx++; nextfile(); nlflg++; ip = ap = nchar = pendt = 0; frame = stk; nxf = frame + STKSIZE; } getname(){ register int i, j, k; lgf++; for(k=0; k < (NS-1); k++){ if(((j=(i=getch()) & CMASK) <= ' ') || (j > 0176))break; nextf[k] = j; } nextf[k] = 0; ch = i; lgf--; return(nextf[0]); } caseso(){ register i, *p, *q; lgf++; if(skip() || !getname() || ((i=open(nextf,0)) <0) || (ifi >= NSO))return; flushi(); ifl[ifi] = ifile; ifile = i; offl[ifi] = ioff; ioff = 0; nx++; nflush++; if(!ifl[ifi++]){ p = ibuf; q = xbuf; xbufp = ibufp; xeibuf = eibuf; while(p < eibuf)*q++ = *p++; } } getpn(a) char *a; { register i, neg; LONG0 atoi1(); neg = 0; ibufp = a; eibuf = -1; noscale++; while((i = getch() & CMASK) != 0)switch(i){ case '+': case ',': continue; case '-': neg = MOT; goto d2; default: ch = i; d2: i = atoi1(); if(nonumb)goto fini; else{ *pnp++ = i | neg; neg = 0; if(pnp >= &pnlist[NPN-2]){ prstr("Too many page numbers\n"); done3(-3); } } } fini: if(neg)*pnp++ = -2; *pnp = -1; ch = noscale = print = 0; pnp = pnlist; chkpn(); } setrpt(){ register i, j; copyf++;raw++; i = getch0(); copyf--;raw--; if((i < 0) || (((j = getch0()) & CMASK) == RPT))return; rchar = j; nchar = i & BMASK; } case '-': neg = MOT; goto #include "tdef.h" #include "t.h" #include "tw.h" /* nroff10.c Device interfaces */ extern int lss; extern char obuf[]; extern char *obufp; extern int xfont; extern int esc; extern int lead; extern int *dip; extern int oline[]; extern int *olinep; extern int ulfont; extern int esct; extern int sps; extern int ics; extern int Hinc, Vinc; extern int ttysave; extern int ttys[3]; extern char termtab[]; extern int ptid; extern int waitf; extern int pipeflg; extern int eqflg; extern int xxx; int bdmode; int plotmode; ptinit(){ register i; register char **p, *q; char *x[8]; if((i = open(termtab,0)) < 0){ prstr("Cannot open "); prstr(termtab); prstr("\n"); exit(-1); } read(i,x,16); read(i,&t.bset,q = 2*(&t.zzz - &t.bset)); x[2] =- q; q = setbrk(x[2]); seek(i,t.twinit+020,0); i = read(i,q,x[2]); q =- t.twinit; for(p = &t.twinit; p < &t.zzz; p++){ if(*p)*p =+ q;else *p = &t.zzz; } sps = EM; ics = EM*2; if(t.bset || t.breset){ ttys[2] =& ~t.breset; ttys[2] =| t.bset; stty(1,ttys); }  oputs(t.twinit); if(eqflg)t.Adj = t.Hor; } twdone(){ oputs(t.twrest); if(pipeflg){ close(ptid); wait(&waitf); } ttys[2] = ttysave; stty(1,ttys); } ptout(i) int i; { *olinep++ = i; if(olinep >= &oline[LNSIZE])olinep--; if((i&CMASK) != '\n')return; olinep--; lead =+ dip->blss + lss - t.Newline; dip->blss = 0; esct = esc = 0; if(olinep>oline){ move(); ptout1(); oputs(t.twnl); }else{ lead =+ t.Newline; move(); } lead =+ dip->alss; dip->alss = 0; olinep = oline; } ptout1() { register i, k; register char *codep; int *q, w, j, phyw; for(q=oline; q>9) & 03; if(t.bdon & 0377){  if(!bdmode && (xfont == 2)){ oputs(t.bdon); bdmode++; } if(bdmode && (xfont != 2)){ oputs(t.bdoff); bdmode = 0; } } if(xfont == ulfont){ for(k=w/t.Char;k>0;k--)oput('_'); for(k=w/t.Char;k>0;k--)oput('\b'); } while(*codep != 0){ if(*codep & 0200){ codep = plot(codep); oputs(t.plotoff); oput(' '); }else{ if(plotmode)oputs(t.plotoff); oput(*codep++); } } if(!w)for(k=phyw/t.Char;k>0;k--)oput('\b'); } } plot(x) char *x; { register int i; register char *j, *k;  if(!plotmode)oputs(t.ploton); k = x; if((*k & 0377) == 0200)k++; for(; *k; k++){ if(*k & 0200){ if(*k & 0100){ if(*k & 040)j = t.up; else j = t.down; }else{ if(*k & 040)j = t.left; else j = t.right; } if(!(i = *k & 037))return(++k); while(i--)oputs(j); }else oput(*k); } return(k); } move(){ register k; register char *i, *j; char *p, *q; if(esct =+ esc)i = "\0"; else i = "\n\0"; j = t.hlf; p = t.right; q = t.down; if(lead){ if(lead < 0){ lead = -lead; if(!esc)i = t.flr; else i = "\0"; j = t.hlr; q = t.up; } if(*i & 0377){ k = lead/t.Newline; lead = lead%t.Newline; while(k--)oputs(i); } if(*j & 0377){ k = lead/t.Halfline; lead = lead%t.Halfline; while(k--)oputs(j); } } if(esc){ if(esc < 0){ esc = -esc; j = "\b"; p = t.left; }else j = " "; k = esc/t.Char; esc = esc%t.Char; while(k--)oputs(j); } if((t.ploton & 0377) && (esc || lead)){ if(!plotmode)oputs(t.ploton); esc =/ t.Hor; lead =/ t.Vert; while(esc--)oputs(p); while(lead--)oputs(q); oputs(t.plotoff); } esc = lead = 0; } oputs(i) char *i; { while(*i != 0)oput(*i++); } ptlead(){move();} dostop(){ int junk; flusho(); read(2,&junk,1); } ead%t.Halfline; while(k--)oputs(j); } } if(esc){ if(esc < 0){ esc = -esc; j = "\b"; p = t.left; }else j = " "; k = esc/t.Char; esc = esc%t.Char; while(k--)oputs(j); } if((t.ploton & 0377) && (esc || lead)){ if(!plotmode)oputs(t.ploton); esc =/ t.Hor; lead =/ t.Vert; while#include "tdef.h" #include "t.h" /* troff2.c output, cleanup */ extern char obuf[OBUFSZ]; extern char *obufp; extern int dilev; extern int *dip; extern int eschar; extern int tlss; extern int tflg; extern int ascii; extern int print; extern char trtab[]; extern int waitf; extern char ptname[]; extern int ptid; extern int offset; extern int em; extern int ds; extern int ip; extern int mflg; extern int woff; extern int nflush; extern int lgf; extern int app; extern int nfo; extern int donef; extern int *frame; extern int *stk; extern int *pendw; extern int nofeed; extern int trap; extern int ttys[3]; extern int quiet; extern int pendnf; extern int ndone; extern int lead; extern int ralss; extern int paper; extern int gflag; extern int *nxf; extern char *unlkp; extern char *nextf[]; extern int pipeflg; extern int ejf; extern int xxx; int toolate; int error; pchar(c) int c; { register i, j; if((i=c) & MOT){pchar1(i); return;} switch(j = i & CMASK){ case 0: case IMP: case RIGHT: case LEFT: return; case HX: j = (tlss>>9) | ((i&~0777)>>3); if(i & 040000){ j =& ~(040000>>3); if(j > dip->blss)dip->blss = j; }else{ if(j > dip->alss)dip->alss = j; ralss = dip->alss; } tlss = 0; return; case LX: tlss = i; return; case PRESC: if(!dip->op)j = eschar; default: i = (trtab[j] & BMASK) | (i & ~CMASK); } pchar1(i); } pchar1(c) int c; { register i, j, *k; extern int chtab[]; j = (i = c) & CMASK; if(dip->op){ wbf(i); dip->op = offset; return; } if(!tflg && !print){ if(j == '\n')dip->alss = dip->blss = 0; return; } if(j == FILLER)return; #ifndef NROFF if(ascii){ if(i & MOT){ oput(' '); return; } if(j < 0177){ oput(i); return; } switch(j){ case 0200: case 0210: oput('-'); break; case 0211: oput('f'); oput('i'); break; case 0212: oput('f'); oput('l'); break; case 0213: oput('f'); oput('f'); break; default: for(k=chtab; *++k != j; k++) if(*k == 0)return; oput('\\'); oput('('); oput(*--k & BMASK); oput(*k >> BYTE); } }else #endif ptout(i); } oput(i) char i; { *obufp++ = i; if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); } flusho(){ if(!ascii)*obufp++ = 0; if(!ptid){ while((ptid=open(ptname,1)) < 0){ if(++waitf <=2)prstr("Waiting for Typesetter.\n"); sleep(15); } } toolate =+ write(ptid, obuf, obufp-obuf); obufp = obuf; } done(x) int x;{ register i; error =| x; app = ds = lgf = 0; if(i=em){ donef = -1; em = 0; if(control(i,0))reset(); } if(!nfo)done3(0); mflg = 0; dip = &d[0]; if(woff)wbt(0); if(pendw)getword(1); pendnf = 0; if(donef == 1)done1(0); donef = 1; ip = 0; frame = stk; nxf = frame + STKSIZE; if(!ejf)tbreak(); nflush++; eject(0); reset(); } done1(x) int x; { error =| x; if(v.nl){ trap = 0; eject(0); reset(); } if(nofeed){ ptlead(); flusho(); done3(0); }else{ if(!gflag)lead =+ TRAILER; done2(0); } } done2(x) int x; { register i; ptlead(); #ifndef NROFF if(!ascii){ oput(T_INIT); oput(T_STOP); if(!gflag)for(i=8; i>0; i--)oput(T_PAD); } #endif flusho(); done3(x); } done3(x) int x;{ error =| x; signal(SIGINT, 1); signal(SIGKILL,1); unlink(unlkp); #ifdef NROFF twdone(); #endif if(quiet){ ttys[2] =| ECHO; stty(0,ttys); } if(ascii)mesg(1); #ifndef NROFF report(); #endif exit(error); } edone(x) int x;{ frame = stk; nxf = frame + STKSIZE; ip = 0; done(x); } #ifndef NROFF report(){ register i; struct {int use; char uid;} a; if((ptid != 1) && paper && ((i=open("/usr/jfo/tr.acct",1)) >0)){ seek(i,0,2); a.use = paper; a.uid = getuid(); write(i,&a,3); close(i); } } #endif #ifdef NROFF casepi(){ register i; int id[2]; if(toolate || skip() || !getname() || (pipe(id) == -1) || ((i=fork()) == -1)){ prstr("Pipe not created.\n"); return; } ptid = id[1]; if(i>0){ close(id[0]); toolate++; pipeflg++; return; } close(0); dup(id[0]); close(id[1]); execl(nextf,nextf,0); prstr("Cannot exec: "); prstr(nextf); prstr("\n"); exit(-4); } #endif r/jfo/tr.acct",1)) >0)){ seek(i,0,2); a.use = paper; a.uid = getuid(); write(i,&a,3); close(i); } } #endif #ifdef NROFF casepi(){ register i; int id[2]; if(toolate || skip() || !getname() || (pipe(id) == -1) || ((i=fork()) == -1)){ prstr("Pipe not created.\n"); return; } ptid = id[1]; if(i>0){ close(id[0]); toolate++; pipeflg++; return; } close(0); dup(id[0]); close(id[1]); execl(nextf,nextf,0); prstr("Cannot exec: "); prstr(nextf); prstr("\n"#include "tdef.h" #include "t.h" /* troff3.c macro and string routines, storage allocation */ #define NBLIST 512 /*allocation list*/ #define BLK 64 /*alloc block words*/ extern int ch; extern int ibf; extern int nextb; extern char *enda; extern int lgf; extern int copyf; extern int ch0; extern int ip; extern int app; extern int ds; extern int nlflg; extern int *nxf; extern int *argtop; extern int *ap; extern int nchar; extern int *frame; extern int *stk; extern int pendt; extern int rchar; extern int dilev; extern int *dip; extern int nonumb; extern int lt; extern int nrbits; extern int nform; extern int fmt[]; extern int oldmn; extern int newmn; extern int macerr; extern int apptr; extern int offset; extern int aplnk; extern int diflg; extern int woff; extern int roff; extern int wbfi; extern int po; extern int *cp; extern int xxx; int pagech '%'; int strflg; extern struct contab { int rq; int (*f)(); }contab[NM]; int blist[NBLIST]; int wbuf[BLK]; int rbuf[BLK]; caseig(){ register i; offset = 0; if((i = copyb()) != '.')control(i,1); } casern(){ register i,j; lgf++; skip(); if(((i=getrq())==0) || ((oldmn=findmn(i)) < 0))return; skip(); clrmn(findmn(j=getrq())); if(j)contab[oldmn].rq = (contab[oldmn].rq & MMASK) | j; } caserm(){ lgf++; skip(); clrmn(findmn(getrq())); } caseas(){ app++; caseds(); } caseds(){ ds++; casede(); } caseam(){ app++; casede(); } casede(){ register i, savoff, req; if(dip->op)wbfl(); req = '.'; lgf++; skip(); if((i=getrq())==0)goto de1; if((offset=finds(i)) == 0)goto de1; if(ds)copys(); else req = copyb(); wbfl(); clrmn(oldmn); if(newmn)contab[newmn].rq = i | MMASK; if(apptr){ savoff = offset; offset = apptr; wbt(IMP); offset = savoff; } offset = dip->op; if(req != '.')control(req,1); de1: ds = app = 0; return; } findmn(i) int i; { register j; for(j=0;j= 0){ if(contab[i].rq & MMASK)free(contab[i].f); contab[i].rq = contab[i].f = 0; } } finds(mn) int mn; { register i, savip; oldmn = findmn(mn); newmn = apptr = aplnk = 0; if(app && (oldmn >= 0) && (contab[oldmn].rq & MMASK)){ savip = ip; ip = contab[oldmn].f; oldmn = -1; while((i=rbf()) != 0); apptr = ip; if(!diflg)ip = incoff(ip); nextb = ip; ip = savip; }else{ for(i=0;i 1)done2(02); prstr("Too many string/macro names.\n"); edone(04); return(offset = 0); } contab[i].f = nextb; if(!diflg){ newmn = i; if(oldmn == -1)contab[i].rq = -1; }else{ contab[i].rq = mn | MMASK; } } app = 0; return(offset = nextb); } skip(){ register i; while(((i=getch()) & CMASK) == ' '); ch=i; return(nlflg); } copyb() { register i, j, k; int ii, req, state, savoff; if(skip() || !(j=getrq()))j = '.'; req = j; k = j>>BYTE; j =& BMASK; copyf++; flushi(); nlflg = 0; state = 1; while(1){ i = (ii = getch()) & CMASK; if(state == 3){ if(i == k)break; if(!k){ ch = ii; i = getach(); ch = ii; if(!i)break; } state = 0; goto c0; } if(i == '\n'){ state = 1; nlflg = 0; goto c0; } if((state == 1) && (i == '.')){ state++; savoff = offset; goto c0; } if((state == 2) && (i == j)){ state++; goto c0; } state = 0; c0: if(offset)wbf(ii); } if(offset){ wbfl(); offset = savoff; wbt(0); } copyf--; return(req); } copys() { register i; copyf++; if(skip())goto c0; if(((i=getch()) & CMASK) != '"')wbf(i); while(((i=getch()) & CMASK) != '\n')wbf(i); c0: wbt(0); copyf--; } alloc() { register i; int j; for(i=0;i= BLK)wbfl(); } wbfl(){ if(woff == 0)return; seek(ibf, woff<<1, 0); write(ibf, &wbuf, wbfi<<1); if((woff & (~(BLK-1))) == (roff & (~(BLK-1))))roff = -1; woff = 0; } blisti(i) int i; { return((i-NEV*EVS)/(BLK)); } rbf(){ register i; if((i=rbf0(ip)) == 0){ if(!app)i = popi(); }else{ ip = incoff(ip); } return(i); } rbf0(p) int p; { register i; if((i = (p & (~(BLK-1)))) != roff){ roff = i; seek(ibf, roff<<1, 0); if(read(ibf, &rbuf, BLK<<1) == 0)return(0); } return(rbuf[p & (BLK-1)]); } incoff(p) int p; { register j; if(!((j = (++p)) & (BLK-1))){ if((j = blist[blisti(--p)]) == -1){ prstr("Bad storage allocation.\n"); done2(-5); } } return(j); } popi(){ register int *p; if(frame == stk)return(0); if(strflg)strflg--; p = nxf = frame; *p++ = 0; frame = *p++; ip = *p++; nchar = *p++; rchar = *p++; pendt = *p++; ap = *p++; cp = *p++; ch0 = *p++; return(*p); } pushi(newip) int newip; { register int *p; if((enda - (STKSIZE<<1)) < nxf)setbrk(DELTA); p = nxf; p++; /*nargs*/ *p++ = frame; *p++ = ip; *p++ = nchar; *p++ = rchar; *p++ = pendt; *p++ = ap; *p++ = cp; *p++ = ch0; *p++ = ch; cp = nchar = rchar = pendt = ap = ch0 = ch = 0; frame = nxf; if(*nxf == 0) nxf =+ STKSIZE; else nxf = argtop; return(ip = newip); } setbrk(x) char *x; { register char *i; char *sbrk(); if((i = sbrk(x)) == -1){ prstrfl("Core limit reached.\n"); edone(0100); }else{ enda = i + x; } return(i); } getsn(){ register i; if((i=getach()) == 0)return(0); if(i == '(')return(getrq()); else return(i); } setstr(){ register i; lgf++; if(((i=getsn()) == 0) || ((i=findmn(i)) == -1) || !(contab[i].rq & MMASK)){ lgf--; return(0); }else{ if((enda-2) < nxf)setbrk(DELTA); *nxf = 0; strflg++; lgf--; return(pushi(contab[i].f)); } } collect() { register i; register int *strp; int *argpp, *argppend; int quote, *savnxf, *lim; copyf++; *nxf = 0; if(skip())goto rtn; savnxf = nxf; lim = nxf =+ 20*STKSIZE; if((argppend = strp = (argpp = savnxf+STKSIZE) + 9) > enda)setbrk(DELTA); while((argpp != argppend) && (!skip())){ *argpp++ = strp; quote = 0; if(((i = getch()) & CMASK) == '"')quote++; else ch = i; while(1){ i = getch(); if( nlflg || ((!quote) && ((i & CMASK) == ' ')))break; if(quote && ((i & CMASK) == '"') && (((i=getch()) & CMASK) != '"')){ ch = i; break; } *strp++ = i; if(strflg && (strp >= lim)){ prstrfl("Macro argument too long.\n"); copyf--; edone(004); } if((enda-4) <= strp)setbrk(DELTA); } *strp++ = 0; } nxf = savnxf; *nxf = argpp - nxf - STKSIZE; argtop = strp; rtn: copyf--; } seta() { register i; if(((i = (getch() & CMASK) - '0') > 0) && (i <= 9) && (i <= *frame))ap = *(i + frame + STKSIZE -1); } caseda(){ app++; casedi(); } casedi(){ register i, j; lgf++; if(skip() || ((i=getrq()) == 0)){ if(dip->op > 0)wbt(0); if(dilev > 0){ v.dn = dip->dnl; v.dl = dip->maxl; dip = &d[--dilev]; offset = dip->op; } goto rtn; } if(++dilev == NDI){ --dilev; prstr("Cannot divert.\n"); edone(02); } if(dip->op)wbt(0); diflg++; dip = &d[dilev]; dip->op = finds(i); dip->curd = i; clrmn(oldmn); for(j=1; j<=10; j++)dip[j] = 0; /*not op and curd*/ rtn: app = 0; diflg = 0; } casedt(){ lgf++; dip->dimac = dip->ditrap = dip->ditf = 0; skip(); dip->ditrap = vnumb(0); if(nonumb)return; skip(); dip->dimac = getrq(); } casetl(){ register i; int w1, w2, w3, begin, delim; extern width(), pchar(); dip->nls = 0; skip(); if(dip->op)wbfl(); if((offset = begin = alloc()) == 0)return; if((delim = getch()) & MOT){ ch = delim; delim = '\''; }else delim =& CMASK; if(!nlflg)  while(((i = getch()) & CMASK) != '\n'){ if((i & CMASK) == delim)i = 004; wbf(i); } wbf(004);wbf(004);wbt(0); w1 = hseg(width,begin); w2 = hseg(width,0); w3 = hseg(width,0); offset = dip->op; #ifdef NROFF if(!offset)horiz(po); #endif hseg(pchar,begin); if(w2 || w3)horiz((lt - w2)/2-w1); hseg(pchar,0); if(w3){ horiz((lt - w2)/2 - w3); hseg(pchar,0); } newline(0); if(*dip){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} else{if(v.nl > dip->hnl)dip->hnl = v.nl;} free(begin); } casepc(){ pagech = chget(IMP); } hseg(f,p) int (*f)(); int *p; { register acc, i; static int *q; acc = 0; if(p)q = p; while(1){ i = rbf0(q); q = incoff(q); if(!i || (i == 004))return(acc); if((i & CMASK) == pagech){ nrbits = i & ~CMASK; nform = fmt[findr('%')]; acc =+ fnumb(v.pn,f); }else acc =+ (*f)(i); } } casepm(){ register i, k; register char *p; int j, xx, cnt, kk, tot; char pmline[10]; kk = cnt = 0; tot = !skip(); for(i = 0; i> BYTE) & 0177))*(p-1) = ' '; *p++ = ' '; kvt(k,p); prstr(pmline); } } if(tot || (cnt > 1)){ kvt(kk,pmline); prstr(pmline); } } kvt(k,p) int k; char *p; { if(k>=100)*p++ = k/100 + '0'; if(k>=10)*p++ = (k%100)/10 + '0'; *p++ = k%10 + '0'; *p++ = '\n'; *p = 0; } for(i = 0; ihnl; break; case '.d': if(dip->op)i = dip->dnl; else i = v.nl; break; case '.u': i = fi; break; case '.w': i = cwidth; break; case '.x': i = ulfont + 1; break; case '.y': i = font1; break; case '.T': i = dotT; break; case '.z': i = dip->curd; cbuf[0] = i & BMASK; cbuf[1] = (i >> BYTE) & BMASK; cbuf[2] = 0; cp = cbuf; return; default: if((j=findr(i)) == -1)i = 0; else{ i = (vlist[j] = (vlist[j] + inc[j]*f)); nform = fmt[j]; } } setn1(i); cp = &cbuf; } setn1(i) int i; { int j; extern int wrc(); cp = &cbuf; nrbits = 0; j=fnumb(i,wrc); *cp = 0; cp = &cbuf; } findr(i) int i; { register j; static int numerr; if(i == 0)return(-1); for(j=0;j 1)done2(04); else edone(04); } return(j); } fnumb(i,f) int i, (*f)(); { register j; j = 0; if(i < 0){ j = (*f)('-' | nrbits); i = -i; } switch(nform){ default: case '1': case 0: return(decml(i,f) + j); case 'i': case 'I': return(roman(i,f) + j); case 'a': case 'A': return(abc(i,f) + j); } } decml(i,f) int i, (*f)(); { register j,k; k = 0; nform--; if((j=i/10) || (nform > 0))k = decml(j,f); return(k + (*f)((i%10 + '0') | nrbits)); } roman(i,f) int i, (*f)(); { if(!i)return((*f)('0' | nrbits)); if(nform == 'i')return(roman0(i,f,"ixcmz","vldw")); else return(roman0(i,f,"IXCMZ","VLDW")); } roman0(i,f,onesp,fivesp) int i, (*f)(); char *onesp, *fivesp; { register q, rem, k; k = 0; if(!i)return(0); k = roman0(i/10,f,onesp+1,fivesp+1); q = (i=i%10)/5; rem = i%5; if(rem == 4){ k =+ (*f)(*onesp | nrbits); if(q)i = *(onesp+1); else i = *fivesp; return(k =+ (*f)(i | nrbits)); } if(q)k =+ (*f)(*fivesp | nrbits); while(--rem >= 0) k =+ (*f)(*onesp | nrbits); return(k); } abc(i,f) int i, (*f)(); { if(!i)return((*f)('0' | nrbits)); else return(abc0(i-1,f)); } abc0(i,f) int i, (*f)(); { register j, k; k = 0; if(j=i/26)k = abc0(j-1,f); return(k + (*f)((i%26 + nform) | nrbits)); } wrc(i) int i; { if(cp >= &cbuf[NC])return(0); *cp++ = i; return(1); } atoi(){ register i; extern LONG0 atoi0(); return(i=atoi0()); } LONG0 atoi0() { register ii, k, cnt; LONG0 i, acc; extern LONG0 ckph(); i = 0; acc = 0; nonumb = 0; cnt = -1; a0: cnt++; switch((ii=getch()) & CMASK){ default: ch = ii; if(cnt)break; case '+': i = ckph(); if(nonumb)break; acc =+ i; goto a0; case '-': i = ckph(); if(nonumb)break; acc =- i; goto a0; case '*': i = ckph(); if(nonumb)break; acc =* i; goto a0; case '/': i = ckph(); if(nonumb)break; if(i == 0){ prstrfl("Divide by zero.\n"); acc = 0; }else acc =/ i; goto a0; case '%': i = ckph(); if(nonumb)break; acc =% i; goto a0; case '=': if(((ii=getch()) & CMASK) != '=')ch = ii; i = ckph(); if(nonumb){acc = 0; break;} if(i == acc)acc = 1; else acc = 0; goto a0; case '>': k = 0; if(((ii=getch()) & CMASK) == '=')k++; else ch =ii; i = ckph(); if(nonumb){acc = 0; break;} if(acc > (i - k))acc = 1; else acc = 0; goto a0; case '<': k = 0; if(((ii=getch()) & CMASK) == '=')k++; else ch =ii; i = ckph(); if(nonumb){acc = 0; break;} if(acc < (i + k))acc = 1; else acc = 0; goto a0; case ')': break; case '(': acc = atoi0(); goto a0; } return(acc); } LONG0 ckph(){ register i; LONG0 j; extern LONG0 atoi0(); extern LONG0 atoi1(); if(((i = getch()) & CMASK) == '(')j = atoi0(); else{ ch = i; j = atoi1(); } return(j); } LONG0 atoi1() { register i, j, digits; long acc; int neg, abs, field; neg = abs = field = digits = 0; acc = 0; a0: switch((i = getch()) & CMASK){ default: ch = i; break; case '+': goto a0; case '-': neg = 1; goto a0; case '|': abs = 1 + neg; neg = 0; goto a0; } a1: while(((j = ((i = getch()) & CMASK) - '0') >= 0) && (j <= 9)){ field++; digits++; acc = 10*acc + j; } if((i & CMASK) == '.'){ field++; digits = 0; goto a1; } ch = i; if(!field)goto a2; switch((i = getch()) & CMASK){ case 'u': i = j = 1; break; case 'v': /*VSs - vert spacing*/ j = lss; i = 1; break; case 'm': /*Ems*/ j = EM; i = 1; break; case 'n': /*Ens*/ j = EM; #ifndef NROFF i = 2; #endif #ifdef NROFF i = 1; /*Same as Ems in NROFF*/ #endif break; case 'p': /*Points*/ j = INCH; i = 72; break; case 'i': /*Inches*/ j = INCH; i = 1; break; case 'c': /*Centimeters*/ j = INCH*50; i = 127; break; case 'P': /*Picas*/ j = INCH; i = 6; break; default: j = dfact; ch = i; i = dfactd; } if(neg) acc = -acc; if(!noscale){ acc = (acc*j)/i; } if((field != digits) && (digits > 0))while(digits--)acc =/ 10; if(abs){ if(dip->op)j = dip->dnl; else j = v.nl; if(!vflag)j = v.hp; if(abs == 2)j = -j; acc =- j; } a2: nonumb = !field; return(acc); } caserr(){ register i,j; lgf++; skip(); if((i=getrq()) == 0)return; for(j=13; j= '0') && (j <= '9'))k++; } if(!k)k=j; fmt[findr(i)] = k & BMASK; } vnumb(i) int i; { vflag++; dfact = lss; res = VERT; return(inumb(i)); } hnumb(i) int i; { dfact = EM; res = HOR; return(inumb(i)); } inumb(n) int *n; { register i, j, f; f = 0; if(n){ if((j = (i = getch()) & CMASK) == '+')f = 1; else if(j == '-')f = -1; else ch = i; } i = atoi(); if(n && f)i = *n + f*i; i = quant(i,res); vflag = 0; res = dfactd = dfact = 1; if(nonumb)i = 0; return(i); } quant(n,m) int n, m; { register i, neg; neg = 0; if(n<0){ neg++; n = -n; } i = n/m; if((n - m*i) > (m/2))i =+ 1; i =* m; if(neg)i = -i; return(i); } mb(i)); } hnumb(i) int i; { dfact = EM; res = HOR; return(inumb(i)); } inumb(n) int *n; { register i, j, f; f = 0; if(n){ if((j = (i = getch()) & CMASK) == '+')f = 1; else if(j == '-')f = -1; else ch = i; } i = atoi(); if(n && f)i = *n + f*i; i = quant(i,res); vflag = 0; res = dfactd = dfact = 1; if(nonumb)i = 0; return(i); } quant(n,m) int n, m; { register i, neg; neg = 0; if(n<0){ neg++; n = -n; } i = n/m; if((n - #include "tdef.h" #include "t.h" /* troff5.c misc processing requests */ extern int ascii; extern int nonumb; extern int admod; extern int ad; extern int fi; extern int cc; extern int c2; extern int ohc; extern int tabc; extern int dotc; extern int pendnf; extern int hyf; extern int ce; extern int po; extern int po1; extern int nc; extern int in; extern int un; extern int un1; extern int in1; extern int ll; extern int ll1; extern int lt; extern int lt1; extern int nlist[NTRAP]; extern int mlist[NTRAP]; extern int lgf; extern int pl; extern int npn; extern int npnflg; extern int *frame; extern int *dip; extern int copyf; extern char nextf[]; extern int trap; extern int lss; extern int em; extern int evlist[EVLSZ]; extern int evi; extern int ibf; extern int ev; extern int ch; extern int nflush; extern int tty; extern int ttys[3]; extern int quiet; extern int iflg; extern int eschar; extern int lit; extern int *litlev; extern int ls; extern int ls1; extern int tabtab[]; extern char trtab[]; extern int ul; extern int cu; extern int sfont; extern int font; extern int fontlab[]; extern int it; extern int itmac; extern int noscale; extern int ic; extern int icf; extern int ics; extern int *vlist; extern int sv; extern int esc; extern int nn; extern int nms; extern int ndf; extern int lnmod; extern int ni; extern int lnsize; extern int nb; extern int offset; extern int nlflg; extern int apts, apts1, pts, pts1, font, font1; extern int ulfont; extern int ulbit; extern int error; extern int nmbits; extern int chbits; extern int tdelim; extern int xxx; int iflist[NIF]; int ifi; extern struct contab { int rq; int (*f)(); }contab[NM]; casead(){ register i; ad = 1; /*leave admod alone*/ if(skip())return; switch((i = getch()) & CMASK){ case 'r': /*right adj, left ragged*/ admod = 2; break; case 'l': /*left adj, right ragged*/ admod = ad = 0; /*same as casena*/ break; case 'c': /*centered adj*/ admod = 1; break; case 'b': case 'n': admod = 0; break; } } casena(){ ad = 0; } casefi(){ tbreak(); fi++; pendnf = 0; lnsize = LNSIZE; } casenf(){ tbreak(); fi = 0; /* can't do while oline is only LNSIZE lnsize = LNSIZE + WDSIZE; */ } casers(){ dip->nls = 0; } casens(){ dip->nls++; } chget(c) int c; { register i; if(skip() || ((i = getch()) & MOT) || ((i&CMASK) == ' ') || ((i&CMASK) == '\n')){ ch = i; return(c); }else return(i & BMASK); } casecc(){ cc = chget('.'); } casec2(){ c2 = chget('\''); } casehc(){ ohc = chget(OHC); } casetc(){ tabc = chget(0); } caselc(){ dotc = chget(0); } casehy(){ register i; hyf = 1; if(skip())return; noscale++; i = atoi(); noscale = 0; if(nonumb)return; hyf = max(i,0); } casenh(){ hyf = 0; } max(aa,bb) int aa,bb; { if(aa>bb)return(aa); else return(bb); } casece(){ register i; noscale++; skip(); i = max(atoi(),0); if(nonumb)i = 1; tbreak(); ce = i; noscale = 0; } casein(){ register i; if(skip())i = in1; else i = max(hnumb(&in),0); tbreak(); in1 = in; in = i; if(!nc){ un = in; setnel(); } } casell(){ register i; if(skip())i = ll1; else i = max(hnumb(&ll),INCH/10); ll1 = ll; ll = i; setnel(); } caselt(){ register i; if(skip())i = lt1; else i = max(hnumb(<),0); lt1 = lt; lt = i; } caseti(){ register i; if(skip())return; i = max(hnumb(&in),0); tbreak(); un1 = i; setnel(); } casels(){ register i; noscale++; if(skip())i = ls1; else i = max(inumb(&ls),1); ls1 = ls; ls = i; noscale = 0; } casepo(){ register i; if(skip())i = po1; else i = max(hnumb(&po),0); po1 = po; po = i; #ifndef NROFF if(!ascii)esc =+ po - po1; #endif } casepl(){ register i; skip(); if((i = vnumb(&pl)) == 0)pl = 11 * INCH; /*11in*/ else pl = i; if(v.nl > pl)v.nl = pl; } casewh(){ register i, j, k; lgf++; skip(); i = vnumb(0); if(nonumb)return; skip(); j = getrq(); if((k=findn(i)) != NTRAP){ mlist[k] = j; return; } for(k=0; kop)return; savframe = frame; skip(); if((i = inumb(&v.pn)) < 0)i = 0; tbreak(); if(!nonumb){ npn = i; npnflg++; }else if(dip->nls)return; eject(savframe); } casetm(){ register i; char tmbuf[NTM]; lgf++; copyf++; skip(); for(i=0; inls || trap)return; i = findt1(); if(!a){ skip(); j = vnumb(0); if(nonumb)j = lss; }else j = a; if(j == 0)return; if(i < j)j = i; savlss = lss; if(dip->op)i = dip->dnl; else i = v.nl; if((i + j) < 0)j = -i; lss = j; newline(0); lss = savlss; } casert(){ register a, *p; skip(); if(dip->op)p = &dip->dnl; else p = &v.nl; a = vnumb(p); if(nonumb)a = dip->mkline; if((a < 0) || (a >= *p))return; nb++; casesp(a - *p); } caseem(){ lgf++; skip(); em = getrq(); } casefl(){ tbreak(); flusho(); } caseev(){ register nxev; extern int block; if(skip()){ e0: if(evi == 0)return; nxev = evlist[--evi]; goto e1; } noscale++; nxev = atoi(); noscale = 0; if(nonumb)goto e0; flushi(); if((nxev >= NEV) || (nxev < 0) || (evi >= EVLSZ)){ prstrfl("Cannot do ev.\n"); if(error)done2(040);else edone(040); return; } evlist[evi++] = ev; e1: if(ev == nxev)return; seek(ibf, ev*EVS*2, 0); write(ibf, &block, EVS*2); seek(ibf, nxev*EVS*2, 0); read(ibf, &block, EVS*2); ev = nxev; } caseel(){ if(--ifi < 0){ ifi = 0; iflist[0] = 0; } caseif(2); } caseie(){ if(ifi >= NIF){ prstr("if-else overflow.\n"); ifi = 0; edone(040); } caseif(1); ifi++; } caseif(x) int x; { register i, notflag, true; if(x == 2){ notflag = 0; true = iflist[ifi]; goto i1; } true = 0; skip(); if(((i = getch()) & CMASK) == '!'){ notflag = 1; }else{ notflag = 0; ch = i; } i = atoi(); if(!nonumb){ if(i > 0)true++; goto i1; } switch((i = getch()) & CMASK){ case 'e': if(!(v.pn & 01))true++; break; case 'o': if(v.pn & 01)true++; break; #ifdef NROFF case 'n': true++; case 't': #endif #ifndef NROFF case 't': true++; case 'n': #endif case ' ': break; default: true = cmpstr(i); } i1: true =^ notflag; if(x == 1)iflist[ifi] = !true; if(true){ i2: do{ v.hp = 0; } while(((i = getch()) & CMASK) == ' '); if((i & CMASK) == LEFT)goto i2; ch = i; nflush++; }else{ copyf++; if(eat(LEFT) == LEFT){ while(eatblk(RIGHT,LEFT) != RIGHT)nlflg = 0; } copyf--; } } eatblk(right,left) int right,left; { register i; e0: while(((i = getch() & CMASK) != right) && (i != left) && (i != '\n')); if(i == left){ while((i=eatblk(right,left)) != right)nlflg = 0; goto e0; } return(i); } cmpstr(delim) int delim; { register i, j, p; int begin, cnt, k; int savapts, savapts1, savfont, savfont1, savpts, savpts1; if(delim & MOT)return(0); delim =& CMASK; if(dip->op)wbfl(); if((offset = begin = alloc()) == 0)return(0); cnt = 0; v.hp = 0; savapts = apts; savapts1 = apts1; savfont = font; savfont1 = font1; savpts = pts; savpts1 = pts1; while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){ wbf(i); cnt++; } wbt(0); k = !cnt; if(nlflg)goto rtn; p = begin; apts = savapts; apts1 = savapts1; font = savfont; font1 = savfont1; pts = savpts; pts1 = savpts1; mchbits(); v.hp = 0; while(((j = (i=getch()) & CMASK) != delim) && (j != '\n')){ if(rbf0(p) != i){ eat(delim); k = 0; break; } p = incoff(p); k = !(--cnt); } rtn: apts = savapts; apts1 = savapts1; font = savfont; font1 = savfont1; pts = savpts; pts1 = savpts1; mchbits(); offset = dip->op; free(begin); return(k); } casest(){ dummy(); } caserd(){ lgf++; skip(); getname(); if(!iflg){ if(quiet){ ttys[2] =& ~ECHO; stty(0,ttys); prstrfl(""); /*bell*/ }else{ if(nextf[0]){ prstr(nextf); prstr(":"); }else{ prstr(""); /*bell*/ } } } collect(); tty++; pushi(-1); } rdtty(){ int onechar; onechar = 0; if(read(0, &onechar, 1) == 1){ if(onechar == '\n')tty++; else tty = 1; if(tty != 3)return(onechar); } popi(); tty = 0; if(quiet){ ttys[2] =| ECHO; stty(0,ttys); } return(0); } caseec(){ eschar = chget('\\'); } caseeo(){ eschar = 0; } caseli(){ skip(); lit = max(inumb(0),1); litlev = frame; if((!dip->op) && (v.nl == -1))newline(1); } caseta(){ register i, j; tabtab[0] = nonumb = 0; for(i=0; ((i < (NTAB-1)) && !nonumb); i++){ if(skip())break; tabtab[i] = max(hnumb(&tabtab[max(i-1,0)]),0) & TMASK; if(!nonumb) switch(j = ch & CMASK){ case 'C': tabtab[i] =| CTAB; break; case 'R':  tabtab[i] =| RTAB; break; default: /*includes L*/ break; } nonumb = ch = 0; } tabtab[i] = 0; } casene(){ register i, j; skip(); i = vnumb(0); if(nonumb)i = lss; if(i > (j = findt1())){ i = lss; lss = j; dip->nls = 0; newline(0); lss = i; } } casetr(){ register i, j; lgf++; skip(); while((i = getch() & CMASK) != '\n'){ if((j = getch()) & MOT)return; if((j =& CMASK) == '\n')j = ' '; trtab[i] = j; } } casecu(){ cu++; caseul(); } caseul(){ register i; noscale++; if(skip())i = 1; else i = atoi(); if(ul && (i == 0)){ font = sfont; ul = cu = 0; } if(i){ if(!ul){ sfont = font; font = ulfont; } ul = i; } noscale = 0; mchbits(); } caseuf(){ register i, j; if(skip() || !(i = getrq()) || (i == 'S') || ((j = find(i,fontlab)) == -1)) ulfont = 1; /*default position 2*/ else ulfont = j; #ifdef NROFF if(ulfont == 0)ulfont = 1; #endif ulbit = ulfont<<9; } caseit(){ register i; lgf++; it = itmac = 0; noscale++; skip(); i = atoi(); skip(); if(!nonumb && (itmac = getrq()))it = i; noscale = 0; } casemc(){ register i; if(icf > 1)ic = 0; icf = 0; if(skip())return; ic = getch(); icf = 1; skip(); i = max(hnumb(0),0); if(!nonumb)ics = i; } casemk(){ register i, j; if(dip->op)j = dip->dnl; else j = v.nl; if(skip()){ dip->mkline = j; return; } if((i = getrq()) == 0)return; vlist[findr(i)] = j; } casesv(){ register i; skip(); if((i = vnumb(0)) < 0)return; if(nonumb)i = 1; sv =+ i; caseos(); } caseos(){ register savlss; if(sv <= findt1()){ savlss = lss; lss = sv; newline(0); lss = savlss; sv = 0; } } casenm(){ register i; lnmod = nn = 0; if(skip())return; lnmod++; noscale++; i = inumb(&v.ln); if(!nonumb)v.ln = max(i,0); getnm(&ndf,1); getnm(&nms,0); getnm(&ni,0); noscale = 0; nmbits = chbits; } getnm(p,min) int *p, min; { register i; eat(' '); if(skip())return; i = atoi(); if(nonumb)return; *p = max(i,min); } casenn(){ noscale++; skip(); nn = max(atoi(),1); noscale = 0; } ister sav#include "tdef.h" #include "t.h" #include "tw.h" /* troff6.c width functions, sizes and fonts */ extern int eschar; extern int widthp; extern int ohc; extern int xfont; extern int smnt; extern int setwdf; extern char trtab[]; extern int chbits; extern int nonumb; extern int noscale; extern int font; extern int font1; extern int pts; extern int sps; extern int nlflg; extern int nform; extern int dfact; extern int dfactd; extern int lss; extern int lss1; extern int vflag; extern int ch0; extern int level; extern int ch; extern int res; extern int xxx; int fontlab[] {'R','I','B','S',0}; width(c) int c; { register i,j,k; j = c; k = 0; if(j & MOT){ if(j & VMOT)goto rtn; k = j & ~MOTV; if(j & NMOT)k = -k; goto rtn; } if((i = (j & CMASK)) == 010){ k = -widthp; goto rtn; } if(i == PRESC)i = eschar; if((i == ohc) || (i >= 0370))goto rtn; if(j & ZBIT)goto rtn; i = trtab[i] & BMASK; if(i < 040)goto rtn; k = (*(t.codetab[i-32]) & 0177) * t.Char; widthp = k; rtn: return(k); } setch(){ register i,*j,k; extern int chtab[]; if((i = getrq()) == 0)return(0); for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0); k = *(++j) | chbits; return(k); } find(i,j) int i,j[]; { register k; if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k); for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1); return(k); } mchbits(){ register i, j, k; chbits = (((pts)<<2) | font) << (BYTE + 1); sps = width(' ' | chbits); } setps(){ register i,j; if((((i=getch() & CMASK) == '+') || (i == '-')) && (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){ ch = 0; return; } if((i =- '0') == 0){ return; } if((i > 0) && (i <= 9)){ if((i <= 3) && ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){ i = 10*i +j; ch = 0; } } } caseft(){ skip(); setfont(1); } setfont(a) int a; { register i,j; if(a)i = getrq(); else i = getsn(); if(!i || (i == 'P')){ j = font1; goto s0; } if(i == 'S')return; if((j = find(i,fontlab)) == -1)return; s0: font1 = font; font = j; mchbits(); } setwd(){ register i, base, wid; int delim, em, k; int savlevel, savhp, savfont, savfont1; base = v.st = v.sb = wid = v.ct = 0; if((delim = getch() & CMASK) & MOT)return; savhp = v.hp; savlevel = level; v.hp = level = 0; savfont = font; savfont1 = font1; setwdf++; while((((i = getch()) & CMASK) != delim) && !nlflg){ wid =+ width(i); if(!(i & MOT)){ em = 2*t.Halfline; }else if(i & VMOT){ k = i & ~MOTV; if(i & NMOT)k = -k; base =- k; em = 0; }else continue; if(base < v.sb)v.sb = base; if((k=base + em) > v.st)v.st = k; } nform = 0; setn1(wid); v.hp = savhp; level = savlevel; font = savfont; font1 = savfont1; mchbits(); setwdf = 0; } vmot(){ dfact = lss; vflag++; return(mot()); } hmot(){ dfact = EM; return(mot()); } mot(){ register i, j; j = HOR; getch(); /*eat delim*/ if(i = atoi()){ if(vflag)j = VERT; i = makem(quant(i,j)); } getch(); vflag = 0; dfact = 1; return(i); } sethl(k) int k; { register i; i = t.Halfline; if(k == 'u')i = -i; else if(k == 'r')i = -2*i; vflag++; i = makem(i); vflag = 0; return(i); } makem(i) int i; { register j; if((j = i) < 0)j = -j; j = (j & ~MOTV) | MOT; if(i < 0)j =| NMOT; if(vflag)j =| VMOT; return(j); } casefp(){ register i, j, k; skip(); if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3))return; if(skip() || !(j = getrq()))return; fontlab[i] = j; } casevs(){ register i; skip(); vflag++; dfact = INCH; /*default scaling is points!*/ dfactd = 72; res = VERT; i = inumb(&lss); if(nonumb)i = lss1; if(i < VERT)i = VERT; lss1 = lss; lss = i; } xlss(){ register i, j; getch(); dfact = lss; i = quant(atoi(),VERT); dfact = 1; getch(); if((j = i) < 0)j = -j; ch0 = ((j & 03700)<<3) | HX; if(i < 0)ch0 =| 040000; return(((j & 077)<<9) | LX); } caseps(){} caselg(){} casecs(){} casebd(){} casess(){} getlg(i) int i; { return(i); } tlab[i] = j; } casevs(){ register i; skip(); vflag++; dfact = INCH; /*default scaling is points!*/ dfactd = 72; res = VERT; i = inumb(&lss); if(nonumb)#include "tdef.h" #include "t.h" #include "tw.h" #ifdef NROFF #define GETCH gettch #endif #ifndef NROFF #define GETCH getch #endif /* troff7.c text */ extern int *dip; extern int pl; extern int trap; extern int flss; extern int npnflg; extern int npn; extern int stop; extern int nflush; extern int *ejl; extern int ejf; extern int ascii; extern int donef; extern int nc; extern int wch; extern int dpn; extern int ndone; extern int lss; extern int pto; extern int pfrom; extern int print; extern int nlist[NTRAP]; extern int mlist[NTRAP]; extern int *frame; extern int *stk; extern int *pnp; extern int nb; extern int ic; extern int icf; extern int ics; extern int ne; extern int ll; extern int un; extern int un1; extern int in; extern int ls; extern int spread; extern int totout; extern int nwd; extern int *pendw; extern int *linep; extern int line[]; extern int lastl; extern int ch; extern int ce; extern int fi; extern int nlflg; extern int pendt; extern int sps; extern int adsp; extern int pendnf; extern int over; extern int adrem; extern int nel; extern int ad; extern int ohc; extern int hyoff; extern int nhyp; extern int spflg; extern int word[]; extern int *wordp; extern int wne; extern int chbits; extern int cwidth; extern int widthp; extern int hyf; extern int xbitf; extern int vflag; extern int ul; extern int cu; extern int font; extern int sfont; extern int it; extern int itmac; extern int *hyptr[NHYP]; extern int **hyp; extern int *wdstart, *wdend; extern int lnmod; extern int admod; extern int nn; extern int nms; extern int ndf; extern int ni; extern int nform; extern int lnsize; extern int po; extern int ulbit; extern int *vlist; extern int nrbits; extern int nmbits; extern int xxx; int brflg; tbreak(){ register *i, j, pad; trap = 0; if(nb)return; if((!dip->op) && (v.nl == -1)){ newline(1); return; } if(!nc){ setnel(); /* if(pendw || !wch)return; */ if(!wch)return; if(pendw)getword(1); movword(); } *linep = dip->nls = 0; #ifdef NROFF if(!dip->op)horiz(po); #endif if(lnmod)donum(); if(brflg != 1){ totout = 0; lastl = ne; }else lastl = ll - un; if(admod && ad && (brflg != 2)){ lastl = ne; adsp = adrem = 0; #ifdef NROFF if(admod == 1)un =+ quant(nel/2,t.Adj); #endif #ifndef NROFF if(admod == 1)un =+ nel/2; #endif NROFF else if(admod ==2)un =+ nel; } totout++; brflg = 0; if(lastl > dip->maxl)dip->maxl = lastl; horiz(un); for(i = line;nc > 0;){ if(((j = *i++) & CMASK) == ' '){ pad = 0; do{ pad =+ width(j); nc--; }while(((j = *i++) & CMASK) == ' '); i--; pad =+ adsp; if(adrem){ if(adrem < 0){ #ifdef NROFF pad =- t.Adj; adrem =+ t.Adj; }else if((totout&01) || ((adrem/t.Adj)>=(--nwd))){ pad =+ t.Adj; adrem =- t.Adj; #endif #ifndef NROFF pad--; adrem++; }else{ pad++; adrem--; #endif } } horiz(pad); }else{ pchar(j); nc--; } } if(ic){ if((j = ll - un - lastl + ics) > 0)horiz(j); pchar(ic); } if(icf)icf++; else ic = 0; ne = nwd = 0; un = in; setnel(); newline(0); if(*dip){if(dip->dnl > dip->hnl)dip->hnl = dip->dnl;} else{if(v.nl > dip->hnl)dip->hnl = v.nl;} for(j=ls-1; (j >0) && !trap; j--)newline(0); spread = 0; } donum(){ register i, nw; extern pchar(); nrbits = nmbits; nw = width('1' | nrbits); if(nn){ nn--; goto d1; } if(v.ln%ndf){ v.ln++; d1: un =+ nw*(3+nms+ni); return; } i = 0; if(v.ln<100)i++; if(v.ln<10)i++; horiz(nw*(ni+i)); nform = 0; fnumb(v.ln,pchar); un =+ nw*nms; v.ln++; } text(){ register i; static int spcnt; nflush++; if((!dip->op) && (v.nl == -1)){newline(1); return;} setnel(); if(ce || !fi){ nofill(); return; } if(pendw)goto t4; if(pendt)if(spcnt)goto t2; else goto t3; pendt++; if(spcnt)goto t2; while(((i = GETCH()) & CMASK) == ' ')spcnt++; if(nlflg){ t1: nflush = pendt = ch = spcnt = 0; callsp(); return; } ch = i; if(spcnt){ t2: tbreak(); if(nc || wch)goto rtn; un =+ spcnt*sps; spcnt = 0; setnel(); if(trap)goto rtn; if(nlflg)goto t1; } t3: if(spread)goto t5; if(pendw || !wch) t4: if(getword(0))goto t6; if(!movword())goto t3; t5: if(nlflg)pendt = 0; adsp = adrem = 0; if(ad){ adsp = nel/(nwd-1); #ifdef NROFF adsp = (adsp/t.Adj)*t.Adj; #endif adrem = nel - adsp*(nwd-1); } brflg = 1; tbreak(); spread = 0; if(!trap)goto t3; if(!nlflg)goto rtn; t6: pendt = 0; if(!pendw)ckul(); rtn: nflush = 0; } nofill(){ register i, j; if(!pendnf){ over = 0; tbreak(); if(trap)goto rtn; if(nlflg){ ch = nflush = 0; callsp(); return; } adsp = adrem = 0; nwd = 10000; } while((j = ((i = GETCH()) & CMASK)) != '\n'){ if(j == ohc)continue; if(j == CONT){ pendnf++; nflush = 0; flushi(); return; } storeline(i,-1); } if(ce){ ce--; if((i=quant(nel/2,HOR)) > 0)un =+ i; } if(!nc)storeline(FILLER,0); brflg = 2; tbreak(); ckul(); rtn: pendnf = nflush = 0; } callsp(){ register i; if(flss)i = flss; else i = lss; flss = 0; casesp(i); } ckul(){ if(ul && (--ul == 0)){ cu = 0; font = sfont; mchbits(); } if(it && (--it == 0) && itmac)control(itmac,0); } storeline(c,w){ register i; if((c & CMASK) == JREG){ if((i=findr(c>>BYTE)) != -1)vlist[i] = ne; return; } if(linep >= (line + lnsize - 1)){ if(!over){ prstrfl("Line overflow.\n"); over++; c = 0343; w = -1; goto s1; } return; } s1: if(w == -1)w = width(c); ne =+ w; nel =- w; *linep++ = c; nc++; } newline(a) int a; { register i, j, nlss; int opn; if(a)goto nl1; if(dip->op){ j = lss; pchar1(FLSS); if(flss)lss = flss; i = lss + dip->blss; dip->dnl =+ i; pchar1(i); pchar1('\n'); lss = j; dip->blss = flss = 0; if(dip->alss){ pchar1(FLSS); pchar1(dip->alss); pchar1('\n'); dip->dnl =+ dip->alss; dip->alss = 0; } if(dip->ditrap && !dip->ditf && (dip->dnl >= dip->ditrap) && dip->dimac) if(control(dip->dimac,0)){trap++; dip->ditf++;} return; } j = lss; if(flss)lss = flss; nlss = dip->alss + dip->blss + lss; v.nl =+ nlss; #ifndef NROFF if(ascii){dip->alss = dip->blss = 0;} #endif pchar1('\n'); flss = 0; lss = j; if(v.nl < pl)goto nl2; nl1: ejf = dip->hnl = v.nl = 0; ejl = frame; if(donef){ if((!nc && !wch) || ndone)done1(0); ndone++; donef = 0; if(frame == stk)nflush++; } opn = v.pn; v.pn++; if(npnflg){ v.pn = npn; npn = npnflg = 0; } nlpn: if(v.pn == pfrom){ print++; pfrom = -1; }else if(opn == pto){ print = 0; opn = -1; chkpn(); goto nlpn; } if(stop && print){ dpn++; if(dpn >= stop){ dpn = 0; dostop(); } } nl2: trap = 0; if(v.nl == 0){ if((j = findn(0)) != NTRAP) trap = control(mlist[j],0); } else if((i = findt(v.nl-nlss)) <= nlss){ if((j = findn1(v.nl-nlss+i)) == NTRAP){ prstrfl("Trap botch.\n"); done2(-5); } trap = control(mlist[j],0); } } findn1(a) int a; { register i, j; for(i=0; iop){ if(dip->dimac && ((i = dip->ditrap -a) > 0))k = i; return(k); } for(i=0; i i)k = i; return(k); } findt1(){ register i; if(dip->op)i = dip->dnl; else i = v.nl; return(findt(i)); } eject(a) int *a; { register savlss; if(dip->op)return; ejf++; if(a)ejl = a; else ejl = frame; if(trap)return; e1: savlss = lss; lss = findt(v.nl); newline(0); lss = savlss; if(v.nl && !trap)goto e1; } movword(){ register i, w, *wp; int savwch, hys; over = 0; wp = wordp; if(!nwd){ while(((i = *wp++) & CMASK) == ' '){ wch--; wne =- width(i); } wp--; } if((wne > nel) && !hyoff && hyf && (!nwd || (nel > 3*sps)) && (!(hyf & 02) || (findt1() > lss)) )hyphen(wp); savwch = wch; hyp = hyptr; nhyp = 0; while(*hyp && (*hyp <= wp))hyp++; while(wch){ if((hyoff != 1) && (*hyp == wp)){ hyp++; if(!wdstart || ((wp > (wdstart+1)) && (wp < wdend) && (!(hyf & 04) || (wp < (wdend-1))) && (!(hyf & 010) || (wp > (wdstart+2))) ) ){ nhyp++; storeline(IMP,0); } } i = *wp++; w = width(i); wne =- w; wch--; storeline(i,w); } if(nel >= 0){ nwd++; return(0); } xbitf = 1; hys = width(0200); /*hyphen*/ m1: if(!nhyp){ if(!nwd)goto m3; if(wch == savwch)goto m4; } if(*--linep != IMP)goto m5; if(!(--nhyp)) if(!nwd)goto m2; if(nel < hys){ nc--; goto m1; } m2: if(((i = *(linep-1) & CMASK) != '-') && (i != 0203) ){ *linep = (*(linep-1) & ~CMASK) | 0200; w = width(*linep); nel =- w; ne =+ w; linep++; /* hsend(); */ } m3: nwd++; m4: wordp = wp; return(1); m5: nc--; w = width(*linep); ne =- w; nel =+ w; wne =+ w; wch++; wp--; goto m1; } horiz(i) int i; { vflag = 0; if(i)pchar(makem(i)); } setnel(){ if(!nc){ linep = line; if(un1 >= 0){ un = un1; un1 = -1; } nel = ll - un; ne = adsp = adrem = 0; } } getword(x) int x; { register i, j, swp; int noword; noword = 0; if(x)if(pendw){ *pendw = 0; goto rtn; } if(wordp = pendw)goto g1; hyp = hyptr; wordp = word; over = wne = wch = 0; hyoff = 0; while(1){ j = (i = GETCH()) & CMASK; if(j == '\n'){ wne = wch = 0; noword = 1; goto rtn; } if(j == ohc){ hyoff = 1; continue; } if(j == ' '){ storeword(i,cwidth); continue; } break; } swp = widthp; storeword(' ' | chbits, -1); if(spflg){ storeword(' ' | chbits, -1); spflg = 0; } widthp = swp; g0: if(j == CONT){ pendw = wordp; nflush = 0; flushi(); return(1); } if(hyoff != 1){ if(j == ohc){ hyoff = 2; *hyp++ = wordp; if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1; goto g1; } if((j == '-') || (j == 0203) /*3/4 Em dash*/ )if(wordp > word+1){ hyoff = 2; *hyp++ = wordp + 1; if(hyp > (hyptr+NHYP-1))hyp = hyptr+NHYP-1; } } storeword(i,cwidth); g1: j = (i = GETCH()) & CMASK; if(j != ' '){ if(j != '\n')goto g0; j = *(wordp-1) & CMASK; if((j == '.') || (j == '!') || (j == '?'))spflg++; } *wordp = 0; rtn: wdstart = 0; wordp = word; pendw = 0; *hyp++ = 0; setnel(); return(noword); } storeword(c,w) int c, w; { if(wordp >= &word[WDSIZE - 1]){ if(!over){ prstrfl("Word overflow.\n"); over++; c = 0343; w = -1; goto s1; } return; } s1: if(w == -1)w = width(c); wne =+ w; *wordp++ = c; wch++; } #ifdef NROFF extern char trtab[]; gettch(){ register int i, j; if(!((i = getch()) & MOT) && (i & ulbit)){ j = i&CMASK; if(cu && (trtab[j] == ' ')) i = ((i & ~ulbit)& ~CMASK) | '_'; if(!cu && (j>32) && (j<0370) && !(*t.codetab[j-32] & 0200)) i =& ~ulbit; } return(i); } (c,w) int c, w; { if(wordp >= &word[WDSIZE - 1]){ if(!over){ prstrfl("Word overflow.\n"); over++; c = 0343; w = -1; goto s1; } return; } s1: if(w == -1)w = width(c); wne =+ w; *wordp++ = c; wch++; } #ifdef NROFF extern char trtab[]; gettch(){ re#include "tdef.h" /* troff8.c hyphenation */ char hbuf[NHEX]; char *nexth hbuf; int *hyend; extern int *wdstart, *wdend; extern int *hyptr[]; extern int **hyp; extern int hyoff; extern int suffid; extern int sufind[26]; char *sufoff -1; extern int noscale; extern int xxx; #define THRESH 160 /*digram goodness threshold*/ int thresh THRESH; hyphen(wp) int *wp; { register *i, j; i = wp; while(punct(*i++)); if(!alph(*--i))return; wdstart = i++; while(alph(*i++)); hyend = wdend = --i-1; while(punct(*i++)); if(*--i)return; if((wdend-wdstart-4) < 0)return; hyp = hyptr; *hyp = 0; hyoff = 2; if(exword() || suffix())goto rtn; digram(); rtn: *hyp++ = 0; if(*hyptr)for(j = 1; j;){ j = 0; for(hyp = hyptr+1; *hyp != 0; hyp++){ if(*(hyp-1) > *hyp){ j++; i = *hyp; *hyp = *(hyp-1); *(hyp-1) = i; } } } } punct(i) int i; { if(!i || alph(i))return(0); else return(1); } alph(i) int i; { register j; j = i & CMASK; if(((j >= 'A') && (j <= 'Z')) || ((j >= 'a') && (j <= 'z')))  return(1); else return(0); } caseht(){ register i; thresh = THRESH; if(skip())return; noscale++; thresh = atoi(); noscale = 0; } casehw(){ register i, k; register char *j; k = 0; while(!skip()){ if((j = nexth) >= (hbuf + NHEX - 2)){ full: prstr("Exception word list full.\n"); *nexth = 0; return; } while(1){ if((i = getch()) & MOT)continue; if(((i =& CMASK) == ' ') || (i == '\n')){ *j++ = 0; nexth = j; *j = 0; if(i == ' ')break; else return; } if(i == '-'){ k = 0200; continue; } *j++ = i | k; k = 0; if(j >= (hbuf + NHEX - 2))goto full; } } } exword(){ register int *w, i; register char *e; char *save; e = hbuf; while(1){ save = e; if(*e == 0)return(0); w = wdstart; while((*e && (w <= hyend)) && ((*e & 0177) == (*w & CMASK))){e++; w++;}; if(!*e){ if(((w-1) == hyend) || ((w == wdend) && ((i = *w & CMASK) == 's') || (i == 'S'))){ w = wdstart; for(e = save; *e; e++){ if(*e & 0200)*hyp++ = w; if(hyp > (hyptr+NHYP-1)) hyp = hyptr+NHYP-1; w++; } return(1); }else{e++; continue;} }else while(*e++); } } suffix(){ register int *w; register char *s, *s0; int i; char *off; again: if(!alph(i = *hyend & CMASK))return(0); if(i < 'a')i =- 'A'; else i =- 'a'; if(!(off = sufind[i]))return(0); while(1){ if((i = *(s0 = getsuf(off)) & 017) == 0)return(0); off =+ i; s = s0 + i - 1; w = hyend - 1; while(((s > s0) && (w >= wdstart)) && ((*s & 0177) == maplow(*w))){s--; w--;}; if(s == s0)break; } s = s0 + i - 1; w = hyend; if(*s0 & 0200)goto mark; while(s > s0){ w--; if(*s-- & 0200){ mark: hyend = w - 1; if(*s0 & 0100)continue; if(!chkvow(w))return(0); *hyp++ = w; } } if(*s0 & 040)return(0); if(exword())return(1); goto again; } maplow(i) int i; { if((i =& CMASK) < 'a')i =+ 'a' - 'A'; return(i); } vowel(i) int i; { switch(maplow(i)){ case 'a': case 'e': case 'i': case 'o': case 'u': case 'y': return(1); default: return(0); } } chkvow(w) int *w; { while(--w >= wdstart)if(vowel(*w & CMASK))return(w); return(0); } getsuf(x) char *x; { register char *s; register cnt; static char suff[20]; s = suff; for(cnt = ((*s++ = rdsufb(x++)) & 017); cnt > 1; cnt--) *s++ = rdsufb(x++); suff[suff[0] & 017] = 0; return(suff); } #define SBSZ 128 /*suffix file buffer size*/ rdsufb(i) char *i; { register char *j; static char sufbuf[SBSZ]; if((j = i & ~(SBSZ-1)) != sufoff){ seek(suffid, sufoff = j, 0); read(suffid, sufbuf, SBSZ); } return(sufbuf[i & (SBSZ-1)]); } digram(){ register *w, val; int *nhyend, *maxw, maxval; extern char bxh[], bxxh[], xxh[], xhx[], hxx[]; again: if(!(w=chkvow(hyend+1)))return; hyend = w; if(!(w=chkvow(hyend)))return; nhyend = w; maxval = 0; w--; while((++w < hyend) && (w < (wdend-1))){ val = 1; if(w == wdstart)val =* dilook('a',*w,bxh); else if(w == wdstart+1)val =* dilook(*(w-1),*w,bxxh); else val =* dilook(*(w-1),*w,xxh); val =* dilook(*w, *(w+1), xhx); val =* dilook(*(w+1), *(w+2), hxx); if(val > maxval){ maxval = val; maxw = w + 1; } } hyend = nhyend; if(maxval > thresh)*hyp++ = maxw; goto again; } dilook(a,b,t) int a, b; char t[26][13]; { register i, j; i = t[maplow(a)-'a'][(j = maplow(b)-'a')/2]; if(!(j & 01))i =>> 4; return(i & 017); } < (wdend-1))){ val = 1; if(w == wdstart)val =* dilook('a',*w,bxh); else if(w == wdstart+1)val =* dilook(*(w-1),*w,bxxh); else val =* dilook(*(w-1),*w,xxh); val =* dilook(*w, *(w+1), xhx); #include "tdef.h" #include "t.h" #include "tw.h" /* troff9.c misc functions */ extern int cbuf[]; extern int *cp; extern int ch; extern int chbits; extern int dfact; extern int vflag; extern int pts; extern int fc; extern int padc; extern int tabtab[]; extern int nlflg; extern int lss; extern int tabch, ldrch; extern int tabc, dotc; extern int nchar, rchar; extern int xxx; setz(){ register i; if(!((i = getch()) & MOT))i =| ZBIT; return(i); } setline(){ register *i, length, c; int w, cnt, delim, rem, temp; if((delim = getch()) & MOT)return; else delim =& CMASK; vflag = 0; dfact = EM; length = quant(atoi(),HOR); dfact = 1; if(!length){ eat(delim); return; } if(((c = getch()) & CMASK) == delim){ ch = c; c = 0204 | chbits; } w = width(c); i = cbuf; if(length < 0){ *i++ = makem(length); length = -length; } if(!(cnt = length/w)){ *i++ = makem(-(temp = ((w-length)/2))); *i++ = c; *i++ = makem(-(w - length - temp)); goto s1; } if(rem = length%w){ switch(c & CMASK){  case 0204: /*rule*/ case 0224: /*underrule*/ case 0276: /*root en*/ *i++ = c | ZBIT; default: *i++ = makem(rem); } } if(cnt){ *i++ = RPT; *i++ = cnt; *i++ = c; } s1: *i++ = 0; eat(delim); cp = cbuf; } eat(c) int c; { register i; while(((i = getch() & CMASK) != c) && (i != '\n')); return(i); } setov(){ register i, j, k; int *p, delim, o[NOV], w[NOV]; if((delim = getch()) & MOT)return; else delim =& CMASK; for(k=0; (k 0 )break; } type = tabtab[j] & (~TMASK); fp = fbuf; pp = padptr; if(x == savfc){while(1){ if(((j = (i = getch()) & CMASK)) == padc){ npad++; *pp++ = fp; if(pp > (padptr + NPP - 1))break; goto s1; }else if(j == savfc) break; else if(j == '\n'){ temp = j; nlflg = 0; break; } ws =+ width(i); s1: *fp++ = i; if(fp > (fbuf + FBUFSZ -3))break; } if(!npad){ npad++; *pp++ = fp; *fp++ = 0; } *fp++ = temp; *fp++ = 0; temp = i = (j = length-ws)/npad; i = (i/HOR)*HOR; if((j =- i*npad) <0)j = -j; i = makem(i); if(temp <0)i =| NMOT; for(;npad > 0; npad--){ *(*--pp) = i; if(j){ j =- HOR; (*(*pp)) =+ HOR; } } cp = fbuf; j = 0; }else if(type == 0){ /*plain tab or leader*/ if((j = width(rchar)) == 0)nchar = 0; else{ nchar = length /j; length =% j; } if(length)j = length | MOT; else j = getch0(); }else{ /*center tab*/ /*right tab*/ while(((j = (i = getch()) & CMASK) != savtc) && (j != '\n') && (j != savlc)){ ws =+ width(i); *fp++ = i; if(fp > (fbuf +FBUFSZ - 3)) break; } *fp++ = i; *fp++ = 0; if(type == RTAB)length =- ws; else length =- ws/2; /*CTAB*/ if(((j = width(rchar)) == 0) || (length <= 0))nchar = 0; else{ nchar = length/j; length =% j; } length = (length/HOR)*HOR; j = makem(length); cp = fbuf; nlflg = 0; } rtn: fc = savfc; tabch = savtc; ldrch = savlc; return(j); } dummy(){} ab*/ while(((j = (i = getch()) & CMASK) != savtc) && (j != '\n') && (j != savlc)){ ws =+ width(i); *fp++ = i; if(fp > (fbuf +FBUFSZ - 3)) break; } *fp++ = i; #include "tdef.h" char obuf[OBUFSZ]; char *obufp obuf; int r[NN] {'%','nl','yr','hp','ct','dn','mo','dy','dw','ln','dl','st','sb'}; int pto 10000; int pfrom 1; int print 1; char nextf[NS] "/usr/lib/tmac.xxxxx"; int nfi 14; #ifdef NROFF char termtab[NS] "/usr/lib/term/37"; int tti 14; #endif char suftab[] "/usr/lib/suftab"; int init 1; int fc IMP; int eschar '\\'; int pl 11*INCH; int po PO; int dfact 1; int dfactd 1; int res 1; int smnt 4; int ascii ASCII; int ptid PTID; char ptname[] "/dev/cat"; int lg LG; int pnlist[NPN] {-1}; int *pnp pnlist; int npn 1; int npnflg 1; int oldbits -1; int xflg 1; int dpn -1; int totout 1; int ulfont 1; int ulbit 1<<9; int tabch TAB; int ldrch LEADER; int xxx; extern caseds(), caseas(), casesp(), caseft(), caseps(), casevs(), casenr(), caseif(), casepo(), casetl(), casetm(), casebp(), casech(), casepn(), tbreak(), caseti(), casene(), casenf(), casece(), casefi(), casein(), caseli(), casell(), casens(), casemk(), casert(), caseam(), casede(), casedi(), caseda(), casewh(), casedt(), caseit(), caserm(), casern(), casead(), casers(), casena(), casepl(), caseta(), casetr(), caseul(), caselt(), casenx(), caseso(), caseig(), casetc(), casefc(), caseec(), caseeo(), caselc(), caseev(), caserd(), casest(), casefl(), done(), casess(), casefp(), casecs(), casebd(), caselg(), casehc(), casehy(), casenh(), casenm(), casenn(), casesv(), caseos(), casels(), casecc(), casec2(), caseem(), caseaf(), casehw(), casemc(), casepm(), casecu(), casepi(), caserr(), caseuf(), caseie(), caseel(), casepc(), caseht(); struct contab { int rq; int (*f)(); }contab[NM]{ 'ds',caseds, 'as',caseas, 'sp',casesp, 'ft',caseft, 'ps',caseps, 'vs',casevs, 'nr',casenr, 'if',caseif, 'ie',caseie, 'el',caseel, 'po',casepo, 'tl',casetl, 'tm',casetm, 'bp',casebp, 'ch',casech, 'pn',casepn, 'br',tbreak, 'ti',caseti, 'ne',casene, 'nf',casenf, 'ce',casece, 'fi',casefi, 'in',casein, 'li',caseli, 'll',casell, 'ns',casens, 'mk',casemk, 'rt',casert, 'am',caseam, 'de',casede, 'di',casedi, 'da',caseda, 'wh',casewh, 'dt',casedt, 'it',caseit, 'rm',caserm, 'rr',caserr, 'rn',casern, 'ad',casead, 'rs',casers, 'na',casena, 'pl',casepl, 'ta',caseta, 'tr',casetr, 'ul',caseul, 'cu',casecu, 'lt',caselt, 'nx',casenx, 'so',caseso, 'ig',caseig, 'tc',casetc, 'fc',casefc, 'ec',caseec, 'eo',caseeo, 'lc',caselc, 'ev',caseev, 'rd',caserd, 'ab',casest, 'fl',casefl, 'ex',done, 'ss',casess, 'fp',casefp, 'cs',casecs, 'bd',casebd, 'lg',caselg, 'hc',casehc, 'hy',casehy, 'nh',casenh, 'nm',casenm, 'nn',casenn, 'sv',casesv, 'os',caseos, 'ls',casels, 'cc',casecc, 'c2',casec2, 'em',caseem, 'af',caseaf, 'hw',casehw, 'mc',casemc, 'pm',casepm, #ifdef NROFF 'pi',casepi, #endif 'uf',caseuf, 'pc',casepc, 'ht',caseht, }; /* troff environment block */ int block 0; int ics ICS; int ic 0; int icf 0; int chbits 0; int nmbits 0; int apts PS; int apts1 PS; int pts PS; int pts1 PS; int font FT; int font1 FT; int sps SPS; int spacesz SS; int lss VS; int lss1 VS; int ls 1; int ls1 1; int ll LL; int ll1 LL; int lt LL; int lt1 LL; int ad 1; int nms 1; int ndf 1; int fi 1; int cc '.'; int c2 '\''; int ohc OHC; int tdelim IMP; int hyf 1; int hyoff 0; int un1 -1; int tabc 0; int dotc '.'; int adsp 0; int adrem 0; int lastl 0; int nel 0; int admod 0; int *wordp 0; int spflg 0; int *linep 0; int *wdend 0; int *wdstart 0; int wne 0; int ne 0; int nc 0; int nb 0; int lnmod 0; int nwd 0; int nn 0; int ni 0; int ul 0; int cu 0; int ce 0; int in 0; int in1 0; int un 0; int wch 0; int pendt 0; int *pendw 0; int pendnf 0; int spread 0; int it 0; int itmac 0; int lnsize LNSIZE; int *hyptr[NHYP] {0}; int tabtab[NTAB] {DTAB,DTAB*2,DTAB*3,DTAB*4,DTAB*5,DTAB*6,DTAB*7,DTAB*8, DTAB*9,DTAB*10,DTAB*11,DTAB*12,DTAB*13,DTAB*14,DTAB*15,0}; int line[LNSIZE]{0}; int word[WDSIZE]{0}; int blockxxx[EVS-64-NHYP-NTAB-WDSIZE-LNSIZE] {0}; /*spare 7 words*/ int oline[LNSIZE+1]; 0; int nb 0; int lnmod 0; int nwd 0; int nn 0; int ni 0; int ul 0; int cu 0; int ce 0; int in 0; int in1 0; int un 0; int wch 0; int pendt 0; int *pendw 0; int pen#include "tdef.h" /* typewriter driving table structure*/ #ifdef NROFF struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t; int pipeflg; #endif struct {int op,dnl,dimac,ditrap,ditf,alss,blss,nls,mkline, maxl,hnl,curd;} d[NDI]; struct {int pn, nl, yr, hp, ct, dn, mo, dy, dw, ln, dl, st, sb; int vxx[NN-13];} v ; int *vlist &v; int *dip &d[0]; int level; int stdi; int waitf; int nofeed; int quiet; int stop; char ibuf[IBUFSZ]; char xbuf[IBUFSZ]; char *ibufp; char *xbufp; char *eibuf; char *xeibuf; int cbuf[NC]; int *cp; int nx; int mflg; int ch; int cps; int suffid; int sufind[26]; int ibf; int ttyod; int ttys[3]; int iflg; int ioff; char *enda; int rargc; char **argp; char trtab[256]; int lgf; int copyf; int ch0; int cwidth; int ip; int nlflg; int *nxf; int *ap; int *frame; int *stk; int donef; int nflush; int nchar; int rchar; int nfo; int ifile; int padc; int raw; int iline; int ifl[NSO]; int offl[NSO]; int ifi; int flss; int nonumb; int trap; int *litlev; int tflg; int ejf; int *ejl; int lit; int gflag; int dilev; int tlss; int offset; int em; int ds; int woff; int app; int ndone; int lead; int ralss; int paper; int nextb; int *argtop; int nrbits; int nform; int oldmn; int newmn; int macerr; int apptr; int aplnk; int diflg; int roff; int wbfi; int inc[NN]; int fmt[NN]; int evi; int vflag; int noscale; int po1; int nlist[NTRAP]; int mlist[NTRAP]; int evlist[EVLSZ]; int ev; int tty; int sfont; int sv; int esc; int cs; int bd; int widthp; int xpts; int xfont; int code; int setwdf; int ccs; int xbitf; int mfont; int mpts; int pfont; int ppts; int over; int nhyp; int **hyp; int *olinep; int *pslp; int back; int esct; int mcase; int psflg; int verm; int escm; int ttysave; int dotT; int eqflg; acerr; int apptr; int aplnk; int diflg;/* character name tables modified for BTL special font version 4 and Commercial II */ int chtab [] { 'hy', 0200, /*hyphen*/ 'bu', 0201, /*bullet*/ 'sq', 0202, /*square*/ 'em', 0203, /*3/4em*/ 'ru', 0204, /*rule*/ '14', 0205, /*1/4*/ '12', 0206, /*1/2*/ '34', 0207, /*3/4*/ 'mi', 0302, /*equation minus*/ 'fi', 0211, /*fi*/ 'fl', 0212, /*fl*/ 'ff', 0213, /*ff*/ 'Fi', 0214, /*ffi*/ 'Fl', 0215, /*ffl*/ 'de', 0216, /*degree*/ 'dg', 0217, /*dagger*/ 'sc', 0220, /*section*/ 'fm', 0221, /*foot mark*/ 'aa', 0222, /*acute accent*/ 'ga', 0223, /*grave accent*/ 'ul', 0224, /*underrule*/ 'sl', 0225, /*slash (longer)*/ '*a', 0230, /*alpha*/ '*b', 0231, /*beta*/ '*g', 0232, /*gamma*/ '*d', 0233, /*delta*/ '*e', 0234, /*epsilon*/ '*z', 0235, /*zeta*/ '*y', 0236, /*eta*/ '*h', 0237, /*theta*/ '*i', 0240, /*iota*/ '*k', 0241, /*kappa*/ '*l', 0242, /*lambda*/ '*m', 0243, /*mu*/ '*n', 0244, /*nu*/ '*c', 0245, /*xi*/ '*o', 0246, /*omicron*/ '*p', 0247, /*pi*/ '*r', 0250, /*rho*/ '*s', 0251, /*sigma*/ '*t', 0252, /*tau*/ '*u', 0253, /*upsilon*/ '*f', 0254, /*phi*/ '*x', 0255, /*chi*/ '*q', 0256, /*psi*/ '*w', 0257, /*omega*/ '*A', 0101, /*Alpha*/ '*B', 0102, /*Beta*/ '*G', 0260, /*Gamma*/ '*D', 0261, /*Delta*/ '*E', 0105, /*Epsilon*/ '*Z', 0132, /*Zeta*/ '*Y', 0110, /*Eta*/ '*H', 0262, /*Theta*/ '*I', 0111, /*Iota*/ '*K', 0113, /*Kappa*/ '*L', 0263, /*Lambda*/ '*M', 0115, /*Mu*/ '*N', 0116, /*Nu*/ '*C', 0264, /*Xi*/ '*O', 0117, /*Omicron*/ '*P', 0265, /*Pi*/ '*R', 0120, /*Rho*/ '*S', 0266, /*Sigma*/ '*T', 0124, /*Tau*/ '*U', 0270, /*Upsilon*/ '*F', 0271, /*Phi*/ '*X', 0130, /*Chi*/ '*Q', 0272, /*Psi*/ '*W', 0273, /*Omega*/ 'sr', 0274, /*square root*/ 'ts', 0275, /*terminal sigma*/ 'rn', 0276, /*root en*/ '>=', 0277, /*>=*/ '<=', 0300, /*<=*/ '==', 0301, /*identically equal*/ '~=', 0303, /*approx =*/ 'ap', 0304, /*approximates*/ '!=', 0305, /*not equal*/ '->', 0306, /*right arrow*/ '<-', 0307, /*left arrow*/ 'ua', 0310, /*up arrow*/ 'da', 0311, /*down arrow*/ 'eq', 0312, /*equation equal*/ 'mu', 0313, /*multiply*/ 'di', 0314, /*divide*/ '+-', 0315, /*plus-minus*/ 'cu', 0316, /*cup (union)*/ 'ca', 0317, /*cap (intersection)*/ 'sb', 0320, /*subset of*/ 'sp', 0321, /*superset of*/ 'ib', 0322, /*improper subset*/ 'ip', 0323, /* " superset*/ 'if', 0324, /*infinity*/ 'pd', 0325, /*partial derivative*/ 'gr', 0326, /*gradient*/ 'no', 0327, /*not*/ 'is', 0330, /*integral sign*/ 'pt', 0331, /*proportional to*/ 'es', 0332, /*empty set*/ 'mo', 0333, /*member of*/ 'pl', 0334, /*equation plus*/ 'rg', 0335, /*registered*/ 'co', 0336, /*copyright*/ 'br', 0337, /*box vert rule*/ 'ct', 0340, /*cent sign*/ 'dd', 0341, /*dbl dagger*/ 'rh', 0342, /*right hand*/ 'lh', 0343, /*left hand*/ '**', 0344, /*math * */ 'bs', 0345, /*bell system sign*/ 'or', 0346, /*or*/ 'ci', 0347, /*circle*/ 'lt', 0350, /*left top (of big curly)*/ 'lb', 0351, /*left bottom*/ 'rt', 0352, /*right top*/ 'rb', 0353, /*right bot*/ 'lk', 0354, /*left center of big curly bracket*/ 'rk', 0355, /*right center of big curly bracket*/ 'bv', 0356, /*bold vertical*/ 'lf', 0357, /*left floor (left bot of big sq bract)*/ 'rf', 0360, /*right floor (rb of ")*/ 'lc', 0361, /*left ceiling (lt of ")*/ 'rc', 0362, /*right ceiling (rt of ")*/ 0,0}; math * */ 'bs', 0345, /*bell system sign*/ 'or', 0346, /*or*/ 'ci', 0347, /*circle*/ 'lt', 0350, /*left top (of big curly)*/ 'lb', 0351, /*left bottom*/ 'rt', 0352, /*right top*/ 'rb', 0353, /*right bot*/ 'lk', 0354, /*left center of big curly bracket*/ 'rk', 0355, /*right center of big curly bracket*/ 'bv', 0356, /*bold vertical*/ 'lf', 0357, /*left floor (leftextern struct {int op,dnl,dimac,ditrap,ditf,alss,blss,nls,mkline, maxl,hnl,curd;} d[NDI]; extern struct {int pn,nl,yr,hp,ct,dn,mo,dy,dw,ln,dl,st,sb; int vxx[NN-13];} v ; ell system sign*/ 'or', 0346, /*or*/ 'ci', 0347, /*circle*/ 'lt', 0350, /*left top (of big curly)*/ 'lb', 0351, /*left bottom*/ 'rt', 0352, /*right top*/ 'rb', 0353, /*right bot*/ 'lk', 0354, /*left center of big curly bracket*/ 'rk', 0355, /*right center of big curly bracket*/ 'bv', 0356, /*bold vertical*/ 'lf', 0357, /*left floor (left.globl _sub1 _sub1: mov 2(sp),r0 sub 4(sp),2(r0) sbc (r0) rts pc axl,hnl,curd;} d[NDI]; extern struct {int pn,nl,yr,hp,ct,dn,mo,dy,dw,ln,dl,st,sb; int vxx[NN-13];} v ; ell system sign*/ 'or', 0346, /*or*/ 'ci', 0347, /*circle*/ 'lt', 0350, /*left top (of big curly)*/ 'lb', 0351, /*left bottom*/ 'rt', 0352, /*right top*/ 'rb', 0353, /*right bot*/ 'lk', 0354, /*left center of big curly bracket*/ 'rk', 0355, /*right center of big curly bracket*/ 'bv', 0356, /*bold vertical*/ 'lf', 0357, /*left floor (left#include "tdef.h" #include "t.h" /* troff10.c CAT interface */ extern int *olinep; extern int oline[]; extern int *pslp; extern int back; extern int xpts; extern int mpts; extern int po; extern int xflg; extern int line[]; extern int lss; extern int xbitf; extern char obuf[]; extern char *obufp; extern int esct; extern int trflg; extern int cs; extern int smnt; extern int mfont; extern int xfont; extern int code; extern int mcase; extern int esc; extern int lead; extern int paper; extern int cps; extern int psflg; extern int ptid; extern int verm; extern int escm; extern char pstab[], psctab[]; extern int *dip; extern int dpn; extern int ascii; int mrail 0; /*0=LR,1=UR*/ int mmag 1; /*0=UM,1=LM*/ extern int nofeed; extern int gflag; extern int fontlab[]; int papflg; extern int pfont; extern int ppts; extern int oldbits; extern int bd; extern int vflag; extern int xxx; ptinit(){ if(ascii || gflag)return; oput(T_INIT); esc = T_IESC; ptesc(); esct = 0; esc = po; oput(0140); /*some initial lead*/ } ptout(i) int i; { register *k, lw, *j; int ds, de, inith, temp, *slp, dv; int psl[16]; if((i & CMASK) != '\n'){ *olinep++ = i; return; } if(olinep == oline){ lead =+ lss; return; } pslp = psl; *pslp = lw = inith = dv = 0; for(k=oline; kblss + lss; dip->blss = 0; slp = k; scan: temp = esct - po; if(mpts & DBL)temp =- 55; ds = temp - inith; de = lw - temp; if(de >= ds){ back = 0; esc = -ds; for(k=slp; k=slp; --k)ptout0(*k); } if(xflg && (--pslp >= psl))goto scan; olinep = oline; lead =+ dip->alss; dip->alss = 0; } ptout0(i) int i; { register j, k, w; if(i & MOT){ j = i & ~MOTV; if(i & NMOT)j = -j; if(back)j = -j; if(i & VMOT)lead =+ j; else esc =+ j; return; } xbitf = 2; if((i>>BYTE) == oldbits){ xfont = pfont; xpts = ppts; xbitf = 0; }else xbits(i); if((k = (i & CMASK)) < 040){ return; } w = getcw(k-32); if(i & ZBIT)w = 0; if(cs){ j = (cs-w)/2; w = cs - j; }else j = 0; if(back){ k = j; j = -w; w = -k; } esc =+ j; if((!xflg || (xpts == *pslp)) && (code & 077)){ if(code & 0200){ if(smnt)xfont = smnt -1; else goto p1; } if((k=(code>>6)&01)^mcase)oput((mcase=k)+0105); if(xfont != mfont){ mfont = xfont; /* oput(0101 + (mfont & 01)); oput(0103 + (mfont < 2)); */ if(mrail != (xfont&01)) oput(0101 + (mrail=xfont&01)); if(mmag != (xfont<2)) oput(0103 + (mmag=(xfont<2))); } if(xpts != mpts)ptps(); if(lead)ptlead(); if(esc)ptesc(); /* oput(code & 077); */ *obufp++ = code & 077; if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); if(bd){ bd =- 1; if(back)bd = -bd; if(esc =+ bd)ptesc(); oput(code & 077); } }else if(bd){ bd =- 1; if(back)bd = -bd; esc =+ bd; } p1: esc =+ w; return; } ptps(){ register i, j, k; if(psflg)return; if(cps){ psflg++; i = findps(cps); }else i = xpts; for(j=0; (i&077) > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} j = psctab[j]; oput((j & ~0200) | 0120); if((!(mpts & DBL))^(!(j & 0200))){ if(j & 0200)k = 55; else k = -55; esc =+ k; } mpts = i; } ptlead(){ register i, k; if(k = lead < 0)lead = -lead; if(k^verm)oput(0112 + ((verm=k)<<1)); if(((k=lead)%3) == 2)k++; k =/ 3; while(k > 0){ if((i=31) > k)i = k; if(verm)paper =- i; else paper =+ i; oput(((~i) & 037) | 0140); if((paper > (11*144*15)) && !papflg){ prstr("Excessive paper use.\n"); papflg++; if(ptid != 1)done2(0200); } k =- i; } lead = 0; } ptesc(){ register i, j, k; if(k = esc < 0)esc = -esc; if(k^escm)oput(0107 + (escm=k)); k = esc; while(k > 0){ if((i=127) > k)i = k; if(((j = (esct + i*(1-2*escm))) > (46*72+18-T_IESC)) || (j < 0))break; /* oput(~i); */ *obufp++ = ~i; if(obufp == (obuf + OBUFSZ + ascii - 1))flusho(); esct = j; k =- i; } esc = 0; } dostop(){ register i; if(ascii)return; if(!nofeed && !gflag)lead =+ TRAILER; ptlead(); flusho(); oput(T_INIT); oput(T_STOP); if(gflag){ oput('f'); for(i=0; i<4; i++){ oput(fontlab[i] & BMASK); oput((fontlab[i]>>BYTE) & BMASK); } }else for(i=8; i>0; i--)oput(T_PAD); flusho(); mcase = mpts = mfont = mrail = verm = escm = 0; mmag = 1; report(); paper = 0; esc = T_IESC; ptesc(); esct = 0; esc = po; } fp == (obuf + OBUFSZ + ascii - 1))flusho(); esct = j; k =- i; } esc = 0; } dostop(){ register#include "tdef.h" #include "t.h" /* troff6.c width functions, sizes and fonts */ extern int eschar; extern int widthp; extern int ohc; extern int trflg; extern int xpts; extern int xfont; extern int code; extern int smnt; extern int setwdf; extern int cs; extern int ccs; extern int spacesz; extern char trtab[]; extern int xbitf; extern int mfont; extern int mpts; extern int pfont; extern int ppts; extern int oldbits; extern int chbits; extern int nonumb; extern int noscale; extern int font; extern int font1; extern int pts; extern int pts1; extern int apts; extern int apts1; extern int sps; extern int nlflg; extern int nform; extern int dfact; extern int lss; extern int lss1; extern int vflag; extern int ch0; extern int lg; char fontfile[] "/usr/lib/font/XX"; int ffi 14; extern int bd; extern int level; extern int ch; extern int res; extern int ptid; extern int xxx; extern char W1[],W2[],W3[],W4[]; int *fontab[] {W1,W2,W3,W4}; int fontlab[] {'R','I','B','S',0}; char pstab[] {6,7,8,9,10,11,12,14,16,18,20,22,24,28,36,0}; char psctab[] {010,000,001,007,002,003,004,005,0211,006, 0212,0213,0214,0215,0216,0}; int cstab[4], ccstab[4]; int bdtab[4]; int sbold 0; width(c) int c; { register i,j,k; j = c; k = 0; if(j & MOT){ if(j & VMOT)goto rtn; k = j & ~MOTV; if(j & NMOT)k = -k; goto rtn; } if((i = (j & CMASK)) == 010){ k = -widthp; goto rtn; } if(i == PRESC)i = eschar; if((i == ohc) || (i >= 0370))goto rtn; if((j>>BYTE) == oldbits){ xfont = pfont; xpts = ppts; }else xbits(j); if(j & ZBIT)goto rtn; if(!trflg)i = trtab[i] & BMASK; if((i =- 32) < 0)goto rtn; k = getcw(i); if(bd)k =+ bd - 1; if(cs)k = cs; rtn0: widthp = k; rtn: xbitf = trflg = 0; return(k); } getcw(i) int i; { register j, k; register char *p; extern int ldivr, ldiv(); extern char codetab[]; bd = 0; if((code = codetab[i]) & 0200){ if(smnt){ p = fontab[smnt-1]; if(xfont == (sbold-1))bd = bdtab[smnt-1]; goto g0; } code = 0; k = 36; goto g1; } p = fontab[xfont]; g0: if(!i)k = spacesz; else k = *(p + i) & BMASK; if(setwdf)v.ct =| ((k>>6) & 3); g1: k = ldiv(0, (k&077)*(xpts&077),6); if(ldivr >= 3)k++; if(cs = cstab[xfont]){ if(ccs = ccstab[xfont])xpts = ccs; cs = ldiv(0, (cs&077)*(xpts&077), 6); if(ldivr >= 3)cs++; } if(!bd)bd = bdtab[xfont]; return(k); } xbits(i) int i; { register j, k; /* if((j = i >> BYTE) == oldbits){ xfont = pfont; xpts = ppts; goto rtn; } */ j = i >> BYTE; xfont = (j>>1) & 03; if(k = (j>>3) & 017){ xpts = pstab[--k]; if(psctab[k] < 0)xpts =| DBL; oldbits = j; pfont = xfont; ppts = xpts; goto rtn; } switch(xbitf){ case 0: xfont = font; xpts = pts; break; case 1: xfont = pfont; xpts = ppts; break; case 2: xfont = mfont; xpts = mpts; } rtn: xbitf = 0; } setch(){ register i,*j,k; extern int chtab[]; if((i = getrq()) == 0)return(0); for(j=chtab;*j != i;j++)if(*(j++) == 0)return(0); k = *(++j) | chbits; /* if((i & CMASK) == '*'){ if(((i = find('R',fontlab)) < 0) && ((i = find('G',fontlab)) < 0)) return(k); else return((k & ~(03<<(BYTE+1))) | (i<<(BYTE+1))); } */ return(k); } find(i,j) int i,j[]; { register k; if(((k = i-'0') >= 1) && (k <= 4) && (k != smnt))return(--k); for(k=0; j[k] != i; k++)if(j[k] == 0)return(-1); return(k); } caseps(){ register i; if(skip())i = apts1; else{ noscale++; i = inumb(&apts); noscale = 0; if(nonumb)return; } casps1(i); } casps1(i) int i; { if(i <= 0)return; apts1 = apts; apts = i; pts1 = pts; pts = findps(i & 077); mchbits(); } findps(i) int i; { register j, k; for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} if(psctab[j] < 0)k =| DBL; return(k); } mchbits(){ register i, j, k; i = pts & 077; for(j=0; i > (k = pstab[j]);j++)if(!k){k=pstab[--j];break;} chbits = (((++j)<<2) | font) << (BYTE + 1); sps = width(' ' | chbits); } setps(){ register i,j; if((((i=getch() & CMASK) == '+') || (i == '-')) && (((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9))){ if(i == '-')j = -j; ch = 0; casps1(apts+j); return; } if((i =- '0') == 0){ casps1(apts1); return; } if((i > 0) && (i <= 9)){ if((i <= 3) && ((j=(ch = getch() & CMASK) - '0') >= 0) && (j <= 9)){ i = 10*i +j; ch = 0; } casps1(i); } } caseft(){ skip(); setfont(1); } setfont(a) int a; { register i,j; if(a)i = getrq(); else i = getsn(); if(!i || (i == 'P')){ j = font1; goto s0; } if(i == 'S')return; if((j = find(i,fontlab)) == -1)return; s0: font1 = font; font = j; mchbits(); } setwd(){ register i, base, wid; int delim, em, k; int savlevel, savhp, savapts, savapts1, savfont, savfont1, savpts, savpts1; base = v.st = v.sb = wid = v.ct = 0; if((delim = getch() & CMASK) & MOT)return; savhp = v.hp; savlevel = level; v.hp = level = 0; savapts = apts; savapts1 = apts1; savfont = font; savfont1 = font1; savpts = pts; savpts1 = pts1; setwdf++; while((((i = getch()) & CMASK) != delim) && !nlflg){ wid =+ width(i); if(!(i & MOT)){ em = (xpts & 077)*6; }else if(i & VMOT){ k = i & ~MOTV; if(i & NMOT)k = -k; base =- k; em = 0; }else continue; if(base < v.sb)v.sb = base; if((k=base + em) > v.st)v.st = k; } nform = 0; setn1(wid); v.hp = savhp; level = savlevel; apts = savapts; apts1 = savapts1; font = savfont; font1 = savfont1; pts = savpts; pts1 = savpts1; mchbits(); setwdf = 0; } vmot(){ dfact = lss; vflag++; return(mot()); } hmot(){ dfact = 6 * (pts & 077); return(mot()); } mot(){ register i, j; j = HOR; getch(); /*eat delim*/ if(i = atoi()){ if(vflag)j = VERT;  i = makem(quant(i,j)); } getch(); vflag = 0; dfact = 1; return(i); } sethl(k) int k; { register i; i = 3 * (pts & 077); if(k == 'u')i = -i; else if(k == 'r')i = -2*i; vflag++; i = makem(i); vflag = 0; return(i); } makem(i) int i; { register j; if((j = i) < 0)j = -j; j = (j & ~MOTV) | MOT; if(i < 0)j =| NMOT; if(vflag)j =| VMOT; return(j); } getlg(i) int i; { register j, k; v.hp =+ (k = width(i)); switch((j = getch0()) & CMASK){ case 'f': j = (i & ~CMASK) | 0213; break; case 'l': j = (i & ~CMASK) | 0212; break; case 'i': j = (i & ~CMASK) | 0211; break; default: ch0 = j; j = i; } v.hp =- k; return(j); } caselg(){ register i; lg++; if(skip())return; lg = atoi(); } casefp(){ register i, j, k; int x; skip(); if(((i = (getch() & CMASK) - '0' -1) < 0) || (i >3))return; if(skip() || !(j = getrq()))return; fontfile[ffi] = j & BMASK; fontfile[ffi+1] = j>>BYTE; if((k = open(fontfile,0)) < 0){ prstr("Cannot open "); c0: prstr(fontfile); prstr("\n"); done(-1); } if(seek(k,16,0) < 0)goto c1; if(read(k,fontab[i],256-32) != 256-32){ c1: prstr("Cannot read "); goto c0; } close(k); if(i == (smnt-1)){smnt = 0; sbold = 0;} if((fontlab[i] = j) == 'S')smnt = i + 1; bdtab[i] = cstab[i] = ccstab[i] = 0; if(ptid != 1){ prstr("Mount font "); prstr(&fontfile[ffi]); prstr(" on "); x = i + '1'; prstr(&x); prstr("\n"); } } casecs(){ register i, j; noscale++; skip(); if(!(i=getrq()) || ((i = find(i,fontlab)) < 0))goto rtn;  skip(); cstab[i] = atoi(); skip(); j = atoi(); if(!nonumb)ccstab[i] = findps(j); rtn: noscale = 0; } casebd(){ register i, j, k; k = 0; bd0: if(skip() || !(i = getrq()) || ((j = find(i,fontlab)) == -1)){ if(k)goto bd1; else return; } if(j == (smnt-1)){ k = smnt; goto bd0; } if(k){ sbold = j + 1; j = k -1; } bd1: skip(); noscale++; bdtab[j] = atoi(); noscale = 0; } casevs(){ register i; skip(); vflag++; dfact = 6; /*default scaling is points!*/ res = VERT; i = inumb(&lss); if(nonumb)i = lss1; if(i < VERT)i = VERT; lss1 = lss; lss = i; } casess(){ register i; noscale++; skip(); if(i = atoi()){ spacesz = i& 0177; sps = width(' ' | chbits); } noscale = 0; } xlss(){ register i, j; getch(); dfact = lss; i = quant(atoi(),VERT); dfact = 1; getch(); if((j = i) < 0)j = -j; ch0 = ((j & 03700)<<3) | HX; if(i < 0)ch0 =| 040000; return(((j & 077)<<9) | LX); } egister i; skip(); vflag++; dfact = 6; /*default scaling is points!*/ res = VERT; i = inumb(/* character name and code tables default width tables modified for BTL special font version 4 and Commercial II */ int chtab [] { 'hy', 0200, /*hyphen*/ 'bu', 0201, /*bullet*/ 'sq', 0202, /*square*/ 'em', 0203, /*3/4em*/ 'ru', 0204, /*rule*/ '14', 0205, /*1/4*/ '12', 0206, /*1/2*/ '34', 0207, /*3/4*/ 'mi', 0302, /*equation minus*/ 'fi', 0211, /*fi*/ 'fl', 0212, /*fl*/ 'ff', 0213, /*ff*/ 'Fi', 0214, /*ffi*/ 'Fl', 0215, /*ffl*/ 'de', 0216, /*degree*/ 'dg', 0217, /*dagger*/ 'sc', 0220, /*section*/ 'fm', 0221, /*foot mark*/ 'aa', 0222, /*acute accent*/ 'ga', 0223, /*grave accent*/ 'ul', 0224, /*underrule*/ 'sl', 0225, /*slash (longer)*/ '*a', 0230, /*alpha*/ '*b', 0231, /*beta*/ '*g', 0232, /*gamma*/ '*d', 0233, /*delta*/ '*e', 0234, /*epsilon*/ '*z', 0235, /*zeta*/ '*y', 0236, /*eta*/ '*h', 0237, /*theta*/ '*i', 0240, /*iota*/ '*k', 0241, /*kappa*/ '*l', 0242, /*lambda*/ '*m', 0243, /*mu*/ '*n', 0244, /*nu*/ '*c', 0245, /*xi*/ '*o', 0246, /*omicron*/ '*p', 0247, /*pi*/ '*r', 0250, /*rho*/ '*s', 0251, /*sigma*/ '*t', 0252, /*tau*/ '*u', 0253, /*upsilon*/ '*f', 0254, /*phi*/ '*x', 0255, /*chi*/ '*q', 0256, /*psi*/ '*w', 0257, /*omega*/ '*A', 0101, /*Alpha*/ '*B', 0102, /*Beta*/ '*G', 0260, /*Gamma*/ '*D', 0261, /*Delta*/ '*E', 0105, /*Epsilon*/ '*Z', 0132, /*Zeta*/ '*Y', 0110, /*Eta*/ '*H', 0262, /*Theta*/ '*I', 0111, /*Iota*/ '*K', 0113, /*Kappa*/ '*L', 0263, /*Lambda*/ '*M', 0115, /*Mu*/ '*N', 0116, /*Nu*/ '*C', 0264, /*Xi*/ '*O', 0117, /*Omicron*/ '*P', 0265, /*Pi*/ '*R', 0120, /*Rho*/ '*S', 0266, /*Sigma*/ '*T', 0124, /*Tau*/ '*U', 0270, /*Upsilon*/ '*F', 0271, /*Phi*/ '*X', 0130, /*Chi*/ '*Q', 0272, /*Psi*/ '*W', 0273, /*Omega*/ 'sr', 0274, /*square root*/ 'ts', 0275, /*terminal sigma*/ 'rn', 0276, /*root en*/ '>=', 0277, /*>=*/ '<=', 0300, /*<=*/ '==', 0301, /*identically equal*/ '~=', 0303, /*approx =*/ 'ap', 0304, /*approximates*/ '!=', 0305, /*not equal*/ '->', 0306, /*right arrow*/ '<-', 0307, /*left arrow*/ 'ua', 0310, /*up arrow*/ 'da', 0311, /*down arrow*/ 'eq', 0312, /*equation equal*/ 'mu', 0313, /*multiply*/ 'di', 0314, /*divide*/ '+-', 0315, /*plus-minus*/ 'cu', 0316, /*cup (union)*/ 'ca', 0317, /*cap (intersection)*/ 'sb', 0320, /*subset of*/ 'sp', 0321, /*superset of*/ 'ib', 0322, /*improper subset*/ 'ip', 0323, /* " superset*/ 'if', 0324, /*infinity*/ 'pd', 0325, /*partial derivative*/ 'gr', 0326, /*gradient*/ 'no', 0327, /*not*/ 'is', 0330, /*integral sign*/ 'pt', 0331, /*proportional to*/ 'es', 0332, /*empty set*/ 'mo', 0333, /*member of*/ 'pl', 0334, /*equation plus*/ 'rg', 0335, /*registered*/ 'co', 0336, /*copyright*/ 'br', 0337, /*box vert rule*/ 'ct', 0340, /*cent sign*/ 'dd', 0341, /*dbl dagger*/ 'rh', 0342, /*right hand*/ 'lh', 0343, /*left hand*/ '**', 0344, /*math * */ 'bs', 0345, /*bell system sign*/ 'or', 0346, /*or*/ 'ci', 0347, /*circle*/ 'lt', 0350, /*left top (of big curly)*/ 'lb', 0351, /*left bottom*/ 'rt', 0352, /*right top*/ 'rb', 0353, /*right bot*/ 'lk', 0354, /*left center of big curly bracket*/ 'rk', 0355, /*right center of big curly bracket*/ 'bv', 0356, /*bold vertical*/ 'lf', 0357, /*left floor (left bot of big sq bract)*/ 'rf', 0360, /*right floor (rb of ")*/ 'lc', 0361, /*left ceiling (lt of ")*/ 'rc', 0362, /*right ceiling (rt of ")*/ 0,0}; char codetab[256-32] { /*cat codes*/ 00, /*space*/ 0145, /*!*/ 0230, /*"*/ 0337, /*#*/ 0155, /*$*/ 053, /*%*/ 050, /*&*/ 032, /*' close*/ 0132, /*(*/ 0133, /*)*/ 0122, /***/ 0143, /*+*/ 047, /*,*/ 040, /*- hyphen*/ 044, /*.*/ 043, /*/*/ 0110, /*0*/ 0111, /*1*/ 0112, /*2*/ 0113, /*3*/ 0114, /*4*/ 0115, /*5*/ 0116, /*6*/ 0117, /*7*/ 0120, /*8*/ 0121, /*9*/ 0142, /*:*/ 023, /*;*/ 0303, /*<*/ 0140, /*=*/ 0301, /*>*/ 0147, /*?*/ 0222, /*@*/ 0103, /*A*/ 075, /*B*/ 070, /*C*/ 074, /*D*/ 072, /*E*/ 0101, /*F*/ 065, /*G*/ 060, /*H*/ 066, /*I*/ 0105, /*J*/ 0107, /*K*/ 063, /*L*/ 062, /*M*/ 061, /*N*/ 057, /*O*/ 067, /*P*/ 055, /*Q*/ 064, /*R*/ 076, /*S*/ 056, /*T*/ 0106, /*U*/ 071, /*V*/ 0104, /*W*/ 0102, /*X*/ 077, /*Y*/ 073, /*Z*/ 0134, /*[*/ 0241, /*\*/ 0135, /*]*/ 0336, /*^*/ 0240, /*_*/ 030, /*` open*/ 025, /*a*/ 012, /*b*/ 027, /*c*/ 011, /*d*/ 031, /*e*/ 014, /*f*/ 045, /*g*/ 001, /*h*/ 006, /*i*/ 015, /*j*/ 017, /*k*/ 005, /*l*/ 004, /*m*/ 003, /*n*/ 033, /*o*/ 021, /*p*/ 042, /*q*/ 035, /*r*/ 010, /*s*/ 002, /*t*/ 016, /*u*/ 037, /*v*/ 041, /*w*/ 013, /*x*/ 051, /*y*/ 007, /*z*/ 0332, /*{*/ 0151, /*|*/ 0333, /*}*/ 0342, /*~*/ 00, /*narrow space*/ 040, /*hyphen*/ 0146, /*bullet*/ 0154, /*square*/ 022, /*3/4 em*/ 026, /*rule*/ 034, /*1/4*/ 036, /*1/2*/ 046, /*3/4*/ 0123, /*minus*/ 0124, /*fi*/ 0125, /*fl*/ 0126, /*ff*/ 0131, /*ffi*/ 0130, /*ffl*/ 0136, /*degree*/ 0137, /*dagger*/ 0355, /*section*/ 0150, /*foot mark*/ 0334, /*acute accent*/ 0335, /*grave accent*/ 0240, /*underrule*/ 0304, /*slash (longer)*/ 00, /*half nar sp*/ 00, /**/ 0225, /*alpha*/ 0212, /*beta*/ 0245, /*gamma*/ 0211, /*delta*/ 0231, /*epsilon*/ 0207, /*zeta*/ 0214, /*eta*/ 0202, /*theta*/ 0206, /*iota*/ 0217, /*kappa*/ 0205, /*lambda*/ 0204, /*mu*/ 0203, /*nu*/ 0213, /*xi*/ 0233, /*omicron*/ 0221, /*pi*/ 0235, /*rho*/ 0210, /*sigma*/ 0237, /*tau*/ 0216, /*upsilon*/ 0215, /*phi*/ 0227, /*chi*/ 0201, /*psi*/ 0251, /*omega*/ 0265, /*Gamma*/ 0274, /*Delta*/ 0256, /*Theta*/ 0263, /*Lambda*/ 0302, /*Xi*/ 0267, /*Pi*/ 0276, /*Sigma*/ 00, /**/ 0306, /*Upsilon*/ 0255, /*Phi*/ 0242, /*Psi*/ 0257, /*Omega*/ 0275, /*square root*/ 0262, /*terminal sigma (was root em)*/ 0261, /*root en*/ 0327, /*>=*/ 0326, /*<=*/ 0330, /*identically equal*/ 0264, /*equation minus*/ 0277, /*approx =*/ 0272, /*approximates*/ 0331, /*not equal*/ 0354, /*right arrow*/ 0234, /*left arrow*/ 0236, /*up arrow*/ 0223, /*down arrow*/ 0232, /*equation equal*/ 0323, /*multiply*/ 0324, /*divide*/ 0325, /*plus-minus*/ 0260, /*cup (union)*/ 0305, /*cap (intersection)*/ 0270, /*subset of*/ 0271, /*superset of*/ 0350, /*improper subset*/ 0246, /* improper superset*/ 0244, /*infinity*/ 0273, /*partial derivative*/ 0253, /*gradient*/ 0307, /*not*/ 0266, /*integral sign*/ 0247, /*proportional to*/ 0343, /*empty set*/ 0341, /*member of*/ 0353, /*equation plus*/ 0141, /*registered*/ 0153, /*copyright*/ 0346, /*box rule (was parallel sign)*/ 0127, /*cent sign*/ 0345, /*dbl dagger*/ 0250, /*right hand*/ 0340, /*left hand*/ 0347, /*math * */ 0243, /*bell system sign*/ 0226, /*or (was star)*/ 0351, /*circle*/ 0311, /*left top (of big curly)*/ 0314, /*left bottom*/ 0315, /*right top*/ 0317, /*right bot*/ 0313, /*left center of big curly bracket*/ 0316, /*right center of big curly bracket*/ 0312, /*bold vertical*/ 0321, /*left floor (left bot of big sq bract)*/ 0320, /*right floor (rb of ")*/ 0322, /*left ceiling (lt of ")*/ 0310}; /*right ceiling (rt of ")*/ /*modified for Commercial II*/ char W1[256-32] { /*Times Roman widths*/ 12, /*space*/ 12, /*!*/ 0, /*"*/ 0, /*#*/ 19, /*$*/ 29, /*%*/ 28, /*&*/ 12, /*' close*/ 16, /*(*/ 16, /*)*/ 16, /***/ 36, /*+*/ 12, /*,*/ 13, /*- hyphen*/ 10, /*.*/ 17, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 10, /*:*/ 12, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 20, /*?*/ 0, /*@*/ 29+0200, /*A*/ 23+0200, /*B*/ 26+0200, /*C*/ 30+0200, /*D*/ 24+0200, /*E*/ 23+0200, /*F*/ 30+0200, /*G*/ 29+0200, /*H*/ 13+0200, /*I*/ 16+0200, /*J*/ 28+0200, /*K*/ 24+0200, /*L*/ 35+0200, /*M*/ 29+0200, /*N*/ 27+0200, /*O*/ 22+0200, /*P*/ 27+0300, /*Q*/ 27+0200, /*R*/ 20+0200, /*S*/ 24+0200, /*T*/ 29+0200, /*U*/ 27+0200, /*V*/ 36+0200, /*W*/ 28+0200, /*X*/ 27+0200, /*Y*/ 23+0200, /*Z*/ 14, /*[*/ 0, /*\*/ 14, /*]*/ 0, /*^*/ 0, /*_*/ 12, /*` open*/ 17, /*a*/ 20+0200, /*b*/ 16, /*c*/ 20+0200, /*d*/ 18, /*e*/ 13+0200, /*f*/ 18+0100, /*g*/ 21+0200, /*h*/ 10+0200, /*i*/ 9+0300, /*j*/ 20+0200, /*k*/ 10+0200, /*l*/ 32, /*m*/ 21, /*n*/ 20, /*o*/ 19+0100, /*p*/ 19+0100, /*q*/ 14, /*r*/ 15, /*s*/ 12+0200, /*t*/ 21, /*u*/ 20, /*v*/ 26, /*w*/ 20, /*x*/ 18+0100, /*y*/ 17, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 29, /*1/4*/ 29, /*1/2*/ 29, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 24, /*ff*/ 32, /*ffi*/ 32, /*ffl*/ 15, /*degree*/ 20, /*dagger*/ 0, /*section*/ 8, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copyright*/ 0, 19, /*cent*/ }; char W2[256-32] { /*Times Italic widths*/ 12, /*space*/ 13, /*!*/ 0, /*"*/ 0, /*#*/ 19, /*$*/ 27, /*%*/ 26, /*&*/ 11, /*' close*/ 15, /*(*/ 15, /*)*/ 16, /***/ 36, /*+*/ 11, /*,*/ 13, /*- hyphen*/ 11, /*.*/ 9, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 11, /*:*/ 11, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 20, /*?*/ 0, /*@*/ 25+0200, /*A*/ 24+0200, /*B*/ 26+0200, /*C*/ 27+0200, /*D*/ 23+0200, /*E*/ 21+0200, /*F*/ 27+0200, /*G*/ 29+0200, /*H*/ 14+0200, /*I*/ 16+0200, /*J*/ 28+0200, /*K*/ 24+0200, /*L*/ 34+0200, /*M*/ 27+0200, /*N*/ 27+0200, /*O*/ 22+0200, /*P*/ 27+0300, /*Q*/ 27+0200, /*R*/ 20+0200, /*S*/ 23+0200, /*T*/ 28+0200, /*U*/ 25+0200, /*V*/ 36+0200, /*W*/ 24+0200, /*X*/ 24+0200, /*Y*/ 25+0200, /*Z*/ 13, /*[*/ 0, /*\*/ 13, /*]*/ 0, /*^*/ 0, /*_*/ 11, /*` open*/ 19, /*a*/ 18+0200, /*b*/ 15, /*c*/ 18+0200, /*d*/ 16, /*e*/ 11+0200, /*f*/ 17+0100, /*g*/ 19+0200, /*h*/ 9+0200, /*i*/ 9+0300, /*j*/ 19+0200, /*k*/ 9+0200, /*l*/ 28, /*m*/ 19, /*n*/ 18, /*o*/ 17+0100, /*p*/ 18+0100, /*q*/ 13, /*r*/ 14, /*s*/ 10+0200, /*t*/ 19, /*u*/ 16, /*v*/ 24, /*w*/ 18, /*x*/ 16+0100, /*y*/ 14, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 13, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 27, /*1/4*/ 27, /*1/2*/ 27, /*3/4*/ 36, /*minus*/ 21, /*fi*/ 21, /*fl*/ 21, /*ff*/ 31, /*ffi*/ 31, /*ffl*/ 15, /*degree*/ 19, /*dagger*/ 16, /*section*/ 7, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copyright*/ 0, 19, /*cent*/ }; char W3[256-32] { /*Times Bold widths*/ 12, /*space*/ 13, /*!*/ 0, /*"*/ 0, /*#*/ 18, /*$*/ 28, /*%*/ 27, /*&*/ 12, /*' close*/ 16, /*(*/ 16, /*)*/ 18, /***/ 36, /*+*/ 12, /*,*/ 14, /*- hyphen*/ 12, /*.*/ 18, /*/*/ 19+0200, /*0*/ 19+0200, /*1*/ 19+0200, /*2*/ 19+0200, /*3*/ 19+0200, /*4*/ 19+0200, /*5*/ 19+0200, /*6*/ 19+0200, /*7*/ 19+0200, /*8*/ 19+0200, /*9*/ 13, /*:*/ 13, /*;*/ 0, /*<*/ 36, /*=*/ 0, /*>*/ 22, /*?*/ 0, /*@*/ 28+0200, /*A*/ 26+0200, /*B*/ 26+0200, /*C*/ 29+0200, /*D*/ 25+0200, /*E*/ 23+0200, /*F*/ 28+0200, /*G*/ 32+0200, /*H*/ 16+0200, /*I*/ 21+0200, /*J*/ 28+0200, /*K*/ 25+0200, /*L*/ 36+0200, /*M*/ 30+0200, /*N*/ 29+0200, /*O*/ 25+0200, /*P*/ 29+0300, /*Q*/ 28+0200, /*R*/ 23+0200, /*S*/ 25+0200, /*T*/ 29+0200, /*U*/ 27+0200, /*V*/ 36+0200, /*W*/ 27+0200, /*X*/ 28+0200, /*Y*/ 27+0200, /*Z*/ 12, /*[*/ 0, /*\*/ 12, /*]*/ 0, /*^*/ 0, /*_*/ 12, /*` open*/ 19, /*a*/ 19+0200, /*b*/ 16, /*c*/ 19+0200, /*d*/ 17, /*e*/ 13+0200, /*f*/ 18+0100, /*g*/ 22+0200, /*h*/ 12+0200, /*i*/ 12+0300, /*j*/ 23+0200, /*k*/ 12+0200, /*l*/ 32, /*m*/ 22, /*n*/ 18, /*o*/ 20+0100, /*p*/ 19+0100, /*q*/ 15, /*r*/ 17, /*s*/ 13+0200, /*t*/ 21, /*u*/ 19, /*v*/ 27, /*w*/ 21, /*x*/ 19+0100, /*y*/ 17, /*z*/ 0, /*{*/ 2, /*|*/ 0, /*}*/ 0, /*~*/ 6, /*narrow space*/ 14, /*hyphen*/ 27, /*bullet*/ 27, /*square*/ 36, /*3/4 em*/ 18, /*rule*/ 28, /*1/4*/ 28, /*1/2*/ 28, /*3/4*/ 36, /*minus*/ 22, /*fi*/ 22, /*fl*/ 23, /*ff*/ 33, /*ffi*/ 33, /*ffl*/ 15, /*degree*/ 20, /*dagger*/ 0, /*section*/ 9, /*foot mark*/ 0, /*'*/ 0, /*`*/ 0, /*_*/ 0, 3, /*half nar sp*/ 0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0, 20, /*registered*/ 20, /*copyright*/ 0, 19, /*cent*/ }; /* Modified for Commercial II and with +, -, and = for equations */ char W4[256-32] { /*Special font widths*/ 0,0, /*.=Sw+042-40*/ 13, /*"*/ 29, /*#*/ 0,0,0,0, /*.=Sw+074-40*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0, 36, /*<*/ 0, /*.=Sw+076-40*/ 36, /*>*/ 0, /*.=Sw+100-40*/ 36, /*@*/ 0,0,0,0,0,0,0, /*.=Sw+134-40*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0, 15, /*\\*/ 0, /*.=Sw+136-40*/ 15, /*^*/ 18, /*_ underrule*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0, 14, /*{*/ 0, /*.=Sw+175-40*/ 14, /*}*/ 15, /*~*/ 0, /*.=Sw+220-40*/ 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 17, /*section*/ 0, /*.=Sw+222-40*/ 10, /*acute accent*/ 10, /*grave accent*/ 18, /*underrule*/ 15, /*slash (longer)*/ 0, /**/ 0, /**/ 24, /*alpha*/ 23+0300, /*beta*/ 23+0100, /*gamma*/ 19+0200, /*delta*/ 18, /*epsilon*/ 18+0300, /*zeta*/ 23+0100, /*eta*/ 19+0200, /*theta*/ 13, /*iota*/ 21, /*kappa*/ 22+0200, /*lambda*/ 25+0100, /*mu*/ 20, /*nu*/ 20+0300, /*xi*/ 20, /*omicron*/ 27, /*pi*/ 21+0100, /*rho*/ 27, /*sigma*/ 20, /*tau*/ 21, /*upsilon*/ 25+0300, /*phi*/ 22+0100, /*chi*/ 24+0300, /*psi*/ 25, /*omega*/ 24+0200, /*Gamma*/ 26+0200, /*Delta*/ 28+0200, /*Theta*/ 28+0200, /*Lambda*/ 27+0200, /*Xi*/ 29+0200, /*Pi*/ 25+0200, /*Sigma*/ 0, /**/ 28+0200, /*Upsilon*/ 29+0200, /*Phi*/ 32+0200, /*Psi*/ 36+0200, /*Omega*/ 30, /*square root*/ 18+0100, /*terminal sigma*/ 18, /*root en*/ 36, /*>=*/ 36, /*<=*/ 36, /*identically equal*/ 27, /*minus*/ 36, /*approx =*/ 36, /*approximates*/ 36, /*not equal*/ 36, /*right arrow*/ 36, /*left arrow*/ 18, /*up arrow*/ 18, /*down arrow*/ 27, /*equal*/ 27, /*multiply*/ 27, /*divide*/ 36, /*plus-minus*/ 36, /*cup (union)*/ 36, /*cap (intersection)*/ 36, /*subset of*/ 36, /*superset of*/ 36, /*improper subset*/ 36, /*improper superset*/ 34, /*infinity*/ 21, /*partial derivative*/ 36+0200, /*gradient*/ 22, /*not*/ 24, /*integral sign*/ 27, /*proportional to*/ 28, /*empty set*/ 27, /*member of*/ 27, /*plus*/ 0, 0, 0, /*box vert rule (was 2.)*/ 0, 17, /*dbl dagger*/ 42, /*right hand*/ 42, /*left hand*/ 16, /*math * */ 41, /*bell system sign*/ 9, /*or*/ 27, /*circle*/ 9, /*left top (of big curly)*/ 9, /*left bottom*/ 9, /*right top*/ 9, /*right bot*/ 9, /*left center of big curly bracket*/ 9, /*right center of big curly bracket*/ 9, /*bold vertical*/ 9, /*left floor (left bot of big sq bract)*/ 9, /*right floor (rb of ")*/ 9, /*left ceiling (lt of ")*/ 9 }; /*right ceiling (rt of ")*/ /*plus*/ 0, 0, 0, /*box vert rule (was 2.)*/ 0, 17, /*dbl dagger*/ 42, /*right hand*/ 42, /*left hand*/ 16, /*math *#ifdef NROFF /*NROFF*/ #define EM t.Em #define HOR t.Hor #define VERT t.Vert #define INCH 240 /*increments per inch*/ #define SPS INCH/10 /*space size*/ #define SS INCH/10 /* " */ #define TRAILER 0 #define UNPAD 0227 #define PO 0 /*page offset*/ #define ASCII 1 #define PTID 1 #define LG 0 #define DTAB (8*INCH/10) #define ICS 2*SPS #endif #ifndef NROFF /*TROFF*/ #define INCH 432 /*troff resolution*/ #define SPS 20 /*space size at 10pt; 1/3 Em*/ #define SS 12 /*space size in 36ths of an em*/ #define TRAILER 6048 /*144*14*3 = 14 inches*/ #define UNPAD 027 #define PO 416 /*page offset 26/27ths inch*/ #define HOR 1 #define VERT 3 #define EM (6*(pts&077)) #define ASCII 0 #define PTID 0 #define LG 1 #define DTAB (INCH/2) #define ICS 3*SPS #endif #define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 #define SIGFPE 8 #define SIGKILL 15 #define SIGPIPE 13 #define ECHO 010 /*tty echo mode*/ #define NARSP 0177 /*narrow space*/ #define HNSP 0226 /*half narrow space*/ #define PS 10 /*default point size*/ #define FT 0 /*default font position*/ #define LL 65*INCH/10 /*line length; 39picas=6.5in*/ #define VS INCH/6 /*vert space; 12points*/ #define NN 256 /*number registers*/ #define NIF 5 /*if-else nesting*/ #define NS 64 /*name buffer*/ #define NTM 256 /*tm buffer*/ #define NEV 3 /*environments*/ #define EVLSZ 10 /*size of ev stack*/ #define EVS 3*256 /*environment size in words*/ #define NM 220 /*requests + macros*/ #define DELTA 512 /*delta core bytes*/ #define STKSIZE 10 /*words*/ #define NHYP 10 /*max hyphens per word*/ #define NHEX 128 /*byte size of exception word list*/ #define NTAB 35 /*tab stops*/ #define NSO 5 /*"so" depth*/ #define WDSIZE 170 /*word buffer size*/ #define LNSIZE 480 /*line buffer size*/ #define NDI 5 /*number of diversions*/ #define DBL 0100000 /*double size indicator*/ #define MOT 0100000 /*motion character indicator*/ #define MOTV 0160000 /*clear for motion part*/ #define VMOT 0040000 /*vert motion bit*/ #define NMOT 0020000 /* negative motion indicator*/ #define MMASK 0100000 /*macro mask indicator*/ #define CMASK 0100377 #define ZBIT 0400 /*zero width char*/ #define BMASK 0377 #define BYTE 8 #define IMP 004 /*impossible char*/ #define FILLER 037 #define PRESC 026 #define HX 0376 /*High-order part of xlss*/ #define LX 0375 /*low-order part of xlss*/ #define CONT 025 #define COLON 013 #define XPAR 030 #define ESC 033 #define FLSS 031 #define RPT 014 #define JREG 0374 #define NTRAP 20 /*number of traps*/ #define NPN 20 /*numbers in "-o"*/ #define T_PAD 0101 /*cat padding*/ #define T_INIT 0100 #define T_IESC 16 /*initial offset*/ #define T_STOP 0111 #define NPP 10 /*pads per field*/ #define FBUFSZ 256 /*field buf size words*/ #define OBUFSZ 512 /*bytes*/ #define IBUFSZ 512 /*bytes*/ #define NC 256 /*cbuf size words*/ #define NOV 10 /*number of overstrike chars*/ #define LONG0 long /*long flag for atoi0,1*/ #define ZONE 5 /*5hrs for EST*/ #define TDELIM 032 #define LEFT 035 #define RIGHT 036 #define LEADER 001 #define TAB 011 #define TMASK 037777 #define RTAB 0100000 #define CTAB 0040000 #define OHC 024 T_I/* typewriter driving table structure*/ #ifdef NROFF extern struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t; #endif 001 #define TAB 011 #define TMASK 037777 #define RTAB 0100000 #define CTAB 0040000 #define OHC 024 T_I.nr TN 0 .\" RT - reset everything to normal state .de RT .if !\\n(1T .BG .if !\\n(IK .if !\\n(IF .if !\\n(IX .di .ce 0 .ul 0 .ps \\n(PS .if \\n(VS>40 .vs \\n(VSu .if \\n(VS<=39 .vs \\n(VSp .if \\n(IP .in -\\n(IQn .if !\\n(IP .nr IQ 5 .if \\n(IP .nr IP -1 .ft 1 .bd 1 .ta 5n 10n 15n 20n 25n 30n 35n 40n 45n 50n 55n 60n 65n 70n 75n 80n .fi .. . \"IZ - initialization .de IZ .if \\n(FM=0 .nr FM 1i .nr YY -\\n(FMu .nr XX 0 1 .nr IP 0 .nr IQ 5 .nr PS 10 .nr VS 12 .if !\\n(PD .if n .nr PD 1v .if !\\n(PD .if t .nr PD 0.3v .nr PI 5n .nr ML 3v .ps \\n(PS .if \\n(VS>40 .vs \\n(VSu .if \\n(VS<=39 .vs \\n(VSp .if \\n(IR=0 .nr IR 5n .nr TB 0 .nr LL 6i .ll \\n(LLu .nr LT \\n(.l .lt \\n(LTu .ev 1 .nr FL \\n(LLu*11u/12u .ll \\n(FLu .ps 8 .vs 10p .ev .if \\*(CH .ds CH "\(hy \\\\n(PN \(hy .if n .ds CF "\\*(DY .wh 0 NP .wh -\\n(FMu FO .wh -\\n(FMu/2u BT .. .de TM .if \\n(IM=0 .if \\n(MN=0 .pn 0 .so /usr/lib/tmac.scover .if \\n(IM=0 .if \\n(MN=0 .rm IM .if \\n(IM=0 .if \\n(MN=0 .rm MF .if \\n(IM=0 .if \\n(MN=0 .rm MR .if \\n(.T=0 .pi /usr/bin/col .nr ST 1 .ds QF MEMORANDUM FOR FILE .br .ds MN \\$1 .nr MM \\n(.$ .nr TN 1 .if \\n(.$-1 .ds CA \\$2 .if \\n(.$-2 .ds CC \\$3 .rm RP .rm S0 .rm S2 .rm AX .. . \" IM - internal memorandum .de IM .nr IM 1 .TM \\$1 .rm QF .rm RP .rm MF .rm MR .. . \" MF - memorandum for file. .de MF .nr MN 1 .TM \\$1 \\$2 .rm MR .rm IM .rm RP .rm TM .. . \" MR - memo for record .de MR .nr MN 2 .TM \\$1 \\$2 .ds QF MEMORANDUM FOR RECORD .rm MF .rm RP .rm IM .rm TM .. .de EG .nr MN 3 .TM \\$1 \\$2 .ds QF ENGINEER'S NOTES .rm MF .rm RP .rm IM .rm TM .. .de OK .br .di .di OD .. .de RP .nr ST 2 .pn 0 .rm SG .rm CS .rm TM .rm QF .rm IM .rm MR .rm MF .rm EG .br .. .de TR \" Comp. Sci. Tech Rept series. .nr ST 3 .pn 0 .ds MN \\$1 .rm SG .rm CS .rm TM .rm QF .rm IM .rm MR .rm MF .rm EG .br .. . \"TL - title and initialization .de TL .br .nr TV 1 .if \\n(IM>0 .rm CS .if \\n(MN>0 .rm CS .ME .rm ME .di WT .na .fi .ll 5.0i .if n .if \\n(TN .ll 30 .if t .if \\n(TN .ll 3.5i .ft 3 .if !\\n(TN .ps 12 .if !\\n(TN .rm CS .hy 0 .. .de TX .rs .sp .5i .ce 1000 .if n .ul 1000 .ps 12 .ft 3 .vs 15p .ne 4 .hy 0 .WT .hy 14 .ce 0 .ul 0 .. . \" AU - author(s) .de AU .nr AV 1 .ad .br .di .br .nf .nr NA +1 .ds R\\n(NA \\$1 .ds E\\n(NA \\$2 .di A\\n(NA .ll \\n(LLu .if !\\n(TN .ft 2 .if \\n(TN .ft 3 .if \\n(TN .if n .ll 16 .if \\n(TN .if t .ll 1.4i .ps 10 .. .de AX .ft 1 .rs .ce 1000 .if n .ul 0 .ps 10 .vs 12p .if n .sp 2 .if t .sp .A1 .if n .sp .if t .sp 0.5 .ns .I1 .if \\n(NA-1 .if n .sp 2 .if \\n(NA-1 .if t .sp .A2 .if \\n(NA-1 .if n .sp .if \\n(NA-1 .if t .sp 0.5 .ns .I2 .if \\n(NA-2 .if t .sp .if \\n(NA-2 .if n .sp 2 .A3 .if \\n(NA-2 .if t .sp 0.5 .if \\n(NA-2 .if n .sp .ns .I3 .if \\n(NA-3 .if t .sp .if \\n(NA-3 .if n .sp 2 .A4 .if \\n(NA-3 .if t .sp 0.5 .if \\n(NA-3 .if n .sp .ns .I4 .if \\n(NA-4 .if t .sp .if \\n(NA-4 .if n .sp 2 .A5 .if \\n(NA-4 .if n .sp .if \\n(NA-4 .if t .sp 0.5 .I5 .. . \"AI - authors institution .de AI .br .ft 1 .di .di I\\n(NA .nf .. . \"AB - begin an abstract .de AB .br .di .ul 0 .ce 0 .ll \\n(LTu .nr 1T 1 .nr IK 1 .nr KI 1 .di WB .rs .ce 1 .ft 2 .if n .ul .ll \\n(LTu .if !\\n(.$ ABSTRACT .sp .hy 14 .ul 0 .ce 0 .fi .ft 1 .nr OJ \\n(.i .in +\\n(.lu/12u .ll -\\n(.lu/12u .br .ps \\n(PS .if \\n(VS>40 .vs \\n(VSu .if \\n(VS<=39 .vs \\n(VSp .ti +\\n(PIu .. . \"AE - end of an abstract .de AE .br .di .ll \\n(LLu .ps \\n(PS .if \\n(VS>40 .vs \\n(VSu .if \\n(VS<=39 .vs \\n(VSp .nr 1T 0 .nr IK 0 .in \\n(OJu .di .ce 0 .if \\n(ST=2 .SY .if \\n(ST<3 .rm SY .. . \"S2 - release paper style . \"SY - cover sheet of released paper .de SY .ll \\n(LLu .ns .if \\n(TV .TX .if \\n(AV .AX .rs .ce 0 .nf .sp 3 .WB .sp 3v .FG .sp 3v \\*(DY .fi .. . \"S2 - first text page, released paper format .de S2 .ce 0 .br .SY .rm SY .bp 1 .if \\n(TV .TX .if \\n(AV .AX .rs .ce 0 .ft 1 .ad .. . \"S0- mike lesk conserve paper style .de S0 .ce 0 .br .ll \\n(LLu .ns .if \\n(TV .TX .if \\n(AV .AX .rs .ce 0 .nf .sp 2 .WB .fi .ad .. . \"S3 - CSTR style .de S3 .rs .sp |2.25i .ce 1000 .I1 .if \\n(NA>1 .sp .5 .if \\n(NA>1 .I2 .if \\n(NA>2 .sp .5 .if \\n(NA>2 .I3 .if \\n(NA>3 .sp .5 .if \\n(NA>3 .I4 .if \\n(NA>4 .sp .5 .if \\n(NA>4 .I5 .sp |4i . \"check how long title is: can space extra .25 inch if short .di EZ .WT .di .if \\n(dn<1.5v .if \\n(NA=1 .sp .25i .ft R Computing Science Technical Report No. \\*(MN .sp .if t .ft 3 .if n .ul 100 .ps 12 .vs 15p .hy 0 .WT .hy 14 .ft 1 .if n .ul 0 .ps 10 .vs 12p .sp .ft 1 .A1 .A2 .A3 .A4 .A5 .ce 0 .sp |8.5i .ce 0 \\*(DY .bp 0 .ft 1 .S2 .. . \"SG - signature .de SG .br .KS .in +2u*\\n(.lu/3u .sp 2 .A1 .if \\n(NA-1 .sp 2 .A2 .if \\n(NA-2 .sp 2 .A3 .if \\n(NA-3 .sp 2 .A4 .if \\n(NA-4 .sp 2 .A5 .in \\$1 .br .KE .. . \"Tables. TS - table start, TE - table end .de TS .br .if !\\n(1T .RT .ul 0 .if t .sp 0.5 .if n .sp .if \\$1H .TQ .nr IX 1 .. .de TQ .di TT .nr IT 1 .. .de TH .if \\n(.d>0.5v .nr T. 0 .if \\n(.d>0.5v .T# 0 .di .nr TQ \\n(.i .nr HT 1 .in 0 .TT .in \\n(TQu .mk #T .. .de TE .nr IX 0 .if \\n(IT>0 .if \\n(HT=0 .di .if \\n(IT>0 .if \\n(HT=0 .nr EF \\n(.u .if \\n(IT>0 .if \\n(HT=0 .nf .if \\n(IT>0 .if \\n(HT=0 .TT .if \\n(IT>0 .if \\n(HT=0 .if \\n(EF>0 .fi .nr IT 0 .nr HT 0 .if n .sp 1 .if t .sp 0.5 .. . \"DS - display. If .DS C, center; L, left-adjust; I, indent. .de DS .KS .\\$1D \\$2 \\$1 .. .de D .ID \\$1 .. .de CD .ce 1000 .XD .. .de ID .XD .if t .in +0.5i .if n .in +8 .if \\n(.$ .if !"\\$1"I" .in \\n(OIu .if \\n(.$ .if !"\\$1"I" .in +\\$1n .. .de LD .XD .. .de XD .nf .nr OI \\n(.i .if t .sp 0.5 .if n .sp 1 .. .de BD \" block display: save everything, then center it. .XD .nr BD 1 .di DD .. . \"DE - display end .de DE .ce 0 .in \\n(OIu .if t .sp 0.5 .if n .sp 1 .if \\n(BD>0 .DF .nr BD 0 .KE .fi .. .de DF \" finish a block display to be recentered. .di .if \\n(dl>\\n(BD .nr BD \\n(dl .if \\n(BD<\\n(.l .in (\\n(.lu-\\n(BDu)/2u .ta \\n(.luR .DD .in \\n(OIu .. . \"KS keep - for keep release features. As in IFM .de KS .if \\n(IK=0 .if \\n(IF=0 .KQ .nr IK +1 .. . \"KQ - real keep processor .de KQ .br .nr KI \\n(.i .ev 2 .br .in \\n(KIu .ps \\n(PS .if \\n(VS>40 .vs \\n(VSu .if \\n(VS<=39 .vs \\n(VSp .ll \\n(LLu .lt \\n(LTu .if \\n(NX>0 .ll \\n(CWu .if \\n(NX>0 .lt \\n(CWu .di KK .nr TB 0 .. . \"KF - floating keep .de KF .if !\\n(IK .FQ .nr IK +1 .. . \"FQ real floating keep processor .de FQ .nr KI \\n(.i .ev 2 .br .in \\n(KIu .ps \\n(PS .if \\n(VS>40 .vs \\n(VSu .if \\n(VS<=39 .vs \\n(VSp .ll \\n(LLu .lt \\n(LTu .if \\n(NX>0 .ll \\n(CWu .if \\n(NX>0 .lt \\n(CWu .di KK .nr TB 1 .. . \"KE release - everything between keep and release is together .de KE .if \\n(IK .if !\\n(IK-1 .if \\n(IF=0 .RQ .if \\n(IK .nr IK -1 .. . \"RQ real release .de RQ .br .di .nr NF 0 .if \\n(dn-\\n(.t .nr NF 1 .if \\n(TC .nr NF 1 .if \\n(NF .if !\\n(TB .sp 200 .if !\\n(NF .if \\n(TB .nr TB 0 .nf .\".rs .nr TC 5 .in 0 .ls 1 .if \\n(TB=0 .ev .if \\n(TB=0 .br .if \\n(TB=0 .ev 2 .if \\n(TB=0 .KK .ls .in .ce 0 .if \\n(TB=0 .rm KK .if \\n(TB .da KJ .if \\n(TB \!.KD \\n(dn .if \\n(TB .KK .if \\n(TB .di .nr TC \\n(TB .fi .ev .. .de EQ \"equation, breakout and display .nr EF \\n(.u .rm EE .nr LE 1 \" 1 is center .ds EL \\$1 .if "\\$1"L" .ds EL \\$2 .if "\\$1"L" .nr LE 0 .if "\\$1"C" .ds EL \\$2 .if "\\$1"I" .nr LE 0 .if "\\$1"I" .ds EE \\h'10n' .if "\\$1"I" .if !"\\$3"" .ds EE \\h'\\$3' .if "\\$1"I" .ds EL \\$2 .if \\n(YE>0 .nf .di EZ .. .de EN \" end of a displayed equation .di .rm EZ .nr ZN \\n(dn .if \\n(ZN=0 .if !"\\*(EL"" .nr ZN 1 .lt \\n(.lu .if "\\n(.z"" .if \\n(ZN>0 .if !\\n(nl=\\n(PE .if t .sp .5 .if "\\n(.z"" .if \\n(ZN>0 .if !\\n(nl=\\n(PE .if n .sp 1 .if !"\\n(.z"" .if \\n(ZN>0 .if !\\n(.d=\\n(PE .if t .sp .5 .if !"\\n(.z"" .if \\n(ZN>0 .if !\\n(.d=\\n(PE .if n .sp 1 .pc .if \\n(BD>0 .nr LE 0 \" can't mean centering in this case. .if \\n(ZN>0 .if \\n(LE>0 .tl \(ts\(ts\\*(10\(ts\\*(EL\(ts .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD=0 .tl '\\*(EE\\*(10''\\*(EL' .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD>0 \!\\*(10\\\\t\\*(EL .if \\n(ZN>0 .if \\n(LE=0 .if \\n(BD>0 .if \\n(BD<\\w'\\*(10' .nr BD \\w'\\*(10' .lt \\n(LLu .pc % .if \\n(YE>0 .if \\n(EF>0 .fi .rm EL .rm 10 .if \\n(ZN>0 .if t .sp .5 .if \\n(ZN>0 .if n .sp .if "\\n(.z"" .nr PE \\n(nl .if !"\\n(.z"" .nr PE \\n(.d .. .de ME .if \\n(LL>0 .nr LT \\n(LL .nr YE 1 .if \\n(PO=0 .nr PO \\n(.o .. . \"EM end up macro - process left over keep-release .de EM .br .if \\n(TB=0 .if t .wh -1p CM .if \\n(TB \&\c .if \\n(TB 'bp .if \\n(TB .NP .if \\n(TB .ch CM 160 .. . \"NP new page .de NP .nr PX \\n(.s .nr PF \\n(.f .if t .CM .if \\n(HM=0 .nr HM 1i 'sp \\n(HMu/2u .lt \\n(LTu .ps \\n(PS .ft 1 .PT .ps \\n(PX .ft \\n(PF 'sp \\n(HMu/2u .nr XX 0 1 .nr YY 0-\\n(FMu .ch FO 12i .wh -\\n(FMu FX .ch FO -\\n(FMu .if \\n(MF .FV .nr MF 0 .mk .os .ev 1 .if \\n(TD=0 .if \\n(TC<5 .XK .nr TC 0 .ns .ev .nr TQ \\n(.i .if \\n(IT>0 .in 0 .if \\n(IT>0 .TT .if \\n(IT>0 .in \\n(TQu .mk #T .if t .if \\n(.o+\\n(LL>7.75i .tm Offset + line length exceeds 7.75 inches, too wide .. .de XK .nr TD 1 .nf .ls 1 .rn KJ KL .KL .rm KL .if "\\n(.z"KJ" .di .nr TB 0 .if "\\n(.z"KJ" .nr TB 1 .br .ls .fi .nr TD 0 .. .de KD .nr KM 0 .if "\\n(.z"KJ" .nr KM 1 \" KM is 1 if in a rediversion of keeps .if \\n(KM>0 \!.KD \\$1 .if \\n(KM=0 .if \\n(.t<\\$1 .di KJ .. .de PT .lt \\n(LLu .pc % .nr PN \\n% .if \\n%-1 .tl '\\*(LH'\\*(CH'\\*(RH' .. . \"FO - footer of page .de FO .rn FO FZ .if \\n(K1>0 .tm This memo has a multi-page cover sheet. You are .if \\n(K1>0 .tm rebuked in the name of the Committee on Technical Memoranda. .if \\n(IT>0 .nr T. 1 .if \\n(IT>0 .if \\n(FC=0 .T# 1 .if \\n(IT>0 .br .nr FC +1 .if !\\n(NX .nr WF 0 .nr dn 0 .rn FZ FO .if \\n(XX .XF .nr MF 0 .if \\n(dn .nr MF 1 .if !\\n(WF .nr YY 0-\\n(FMu .if !\\n(WF .ch FO \\n(YYu .if !\\n(dn .nr WF 0 .if \\n(FC<=1 .if \\n(NX>0 .RC .if \\n(FC<=1 .if \\n(NX<=0 'bp .nr FC -1 .if \\n(ML>0 .ne \\n(MLu .. . \"2C - begin double column .de 2C .if !\\n(1T .if n .sp 4 .if !\\n(1T .if t .sp 2 .RT .mk .nr NC 1 .hy 12 .nr NX 1 .nr L1 \\n(.l .if \\n(CW=0 .nr CW \\n(.l*7/15 .ll \\n(CWu .nr FL \\n(CWu*11u/12u .if \\n(GW=0 .nr GW \\n(L1-(2*\\n(CW) .nr RO \\n(CW+\\n(GW .ns .. .de RC .if \\n(NC>1 .C2 .if \\n(NC<=1 .C1 .nr NC \\n(ND .. .de C1 .rt .po +\\n(ROu .nr ND 2 .nr XX 0 1 .if \\n(MF .FV .ev 1 .if \\n(TB .XK .nr TC 0 .ev .ns .. .ch FO \\n(YYu .de C2 .po \\n(POu 'bp .nr ND 1 .. . \"1C - return to single column format .de 1C .br .po \\n(POu .nr ND 1 .if \\n(NX>0 .ll \\n(L1u .if \\n(NX>0 .bp .nr NX 0 .hy 14 .. . \".de R3 . \".pl 102 . \".nr LT \\n(.l . \".. .de MH Bell Laboratories Murray Hill, New Jersey 07974 .. .de PY Bell Laboratories Piscataway, New Jersey 08854 .. .de BT .nr PX \\n(.s .nr PF \\n(.f .ft 1 .ps \\n(PS 'lt \\n(LTu .if \\n%>0 .tl '\\*(LF'\\*(CF'\\*(RF' .ft \\n(PF .ps \\n(PX .. . \"PP - paragraph .de PP .RT .ne 1.1 .if \\n(1T .sp \\n(PDu .ti +\\n(PIu .. . \"SH - (unnumbered) section heading .de SH .RT .if \\n(1T .sp 1 .if !\\n(1T .BG .RT .ne 4 .ft 3 .if n .ul 1000 .. . \"NH - numbered heading .de NH .RT .if \\n(1T .sp 1 .if !\\n(1T .BG .RT .ne 4 .ft 3 .if n .ul 1000 .nr NS \\$1 .if !\\n(.$ .nr NS 1 .if !\\n(NS .nr NS 1 .nr H\\n(NS +1 .if !\\n(NS-4 .nr H5 0 .if !\\n(NS-3 .nr H4 0 .if !\\n(NS-2 .nr H3 0 .if !\\n(NS-1 .nr H2 0 .if !\\$1 .if \\n(.$ .nr H1 1 .ds SN \\n(H1. .if \\n(NS-1 .as SN \\n(H2. .if \\n(NS-2 .as SN \\n(H3. .if \\n(NS-3 .as SN \\n(H4. .if \\n(NS-4 .as SN \\n(H5. \\*(SN .. . \"BG - begin, execute at first PP .de BG .br .ME .rm ME .di .ce 0 .nr KI 0 .hy 14 .nr 1T 1 .S\\n(ST .rm S0 .rm S1 .rm S2 .rm S3 .rm OK .rm OD .rm TX .rm AX .rm WT .rm CS .rm TM .rm IM .rm MF .rm MR .rm RP .rm I1 .rm I2 .rm I3 .rm I4 .rm I5 .rm CB .rm E1 .rm E2 .de TL .ft 3 .sp .if n .ul 100 .ce 100 .LG \\.. .de AU .ft 2 .if n .ul 0 .ce 100 .sp .NL \\.. .de AI .ft 1 .ce 100 .if n .ul 0 .if n .sp .if t .sp .5 .NL \\.. .rn FJ FS .rn FK FE .nf .if \\n(KI=0 .nr FP 0 \"KI should be new .nr KI 0 \"KI should be new .if \\n(FP>0 .FS .if \\n(FP>0 .FG .if \\n(FP>0 .FE .br .if n .sp 2 .if t .sp 1 .fi .ll \\n(LLu .. . \"IP - indented paragraph .de IP .RT .if !\\n(IP .nr IP +1 .sp \\n(PDu .ne 3v .if \\n(.$-1 .nr IQ \\$2 .if \\n(.$ .LB "\\$1" .if !\\n(.$ .LB .. . \"LP - left aligned (block) paragraph .de LP .ti 0 .RT .if \\n(1T .sp \\n(PDu .ne 1.1 .if \\n(.$ .LB \\$1 .. . \"IE - synonym for .LP .de IE .LP .. . \"LB - label paragraph .de LB .in +\\n(IQn .ta \\n(IQn .if \\n(.$ .ti -\\n(IQn .if \\n(.$ \\$1\t\c .. . \"RS - prepare for double indenting .de RS .in +\\n(IRu .. . \"RE - retreat to the left .de RE .br .in -\\n(IRu .. . \"CM - cut mark .de CM .po 0 .lt 7.7i .ft 1 .tl '--''--' .po .lt .ft .. . \"B - bold font .de B .nr PQ \\n(.f .if t .ft 3 .if "\\$1"" .if n .ul 1000 .if !"\\$1"" .if n .ul 1 .if t .if !"\\$1"" \\$1\\f\\n(PQ\\$2 .if n .if \\n(.$=1 \\$1 .if n .if \\n(.$>1 \\$1\\c .if n .if \\n(.$>1 \\&\\$2 .. . \"R - Roman font .de R .if n .ul 0 .ft 1 .. . \"I - italic font .de I .nr PQ \\n(.f .if t .ft 2 .if "\\$1"" .if n .ul 1000 .if !"\\$1"" .if n .ul 1 .if t .if !"\\$1"" \\$1\\f\\n(PQ\\$2 .if n .if \\n(.$=1 \\$1 .if n .if \\n(.$>1 \\$1\\c .if n .if \\n(.$>1 \\&\\$2 .. . \"TA - tabs set in ens or chars .de TA .ta \\$1n \\$2n \\$3n \\$4n \\$5n \\$6n \\$7n \\$8n \\$9n .. . \"SM - make smaller size .de SM .ps -2 .. . \"LG - make larger size .de LG .ps +2 .. . \"NL - return to normal size .de NL .ps \\n(PS .. . \"DA - force date; ND - no date or new date. .de DA .if \\n(.$ .ds DY \\$1 \\$2 \\$3 \\$4 .ds CF \\*(DY .. .de ND .ds DY \\$1 \\$2 \\$3 \\$4 .rm CF .. .if \n(mo-0 .ds MO January .if \n(mo-1 .ds MO February .if \n(mo-2 .ds MO March .if \n(mo-3 .ds MO April .if \n(mo-4 .ds MO May .if \n(mo-5 .ds MO June .if \n(mo-6 .ds MO July .if \n(mo-7 .ds MO August .if \n(mo-8 .ds MO September .if \n(mo-9 .ds MO October .if \n(mo-10 .ds MO November .if \n(mo-11 .ds MO December .if \n(dw-0 .ds DW Sunday .if \n(dw-1 .ds DW Monday .if \n(dw-2 .ds DW Tuesday .if \n(dw-3 .ds DW Wednesday .if \n(dw-4 .ds DW Thursday .if \n(dw-5 .ds DW Friday .if \n(dw-6 .ds DW Saturday .ds DY \*(MO \n(dy, 19\n(yr .IZ .rm IZ .rm MO .de FN .FS .. . \"FS - begin footnote .de FJ 'ce 0 .di .ev1 .ll \\n(FLu .da FF .br .if \\n(IF>0 .tm Footnote within footnote-illegal. .nr IF 1 .if !\\n+(XX-1 .FA .. . \"FE - footnote end .de FK .br .in 0 .nr IF 0 .di .ev .if !\\n(XX-1 .nr dn +\\n(.v .nr YY -\\n(dn .if \\n(NX=0 .nr WF 1 .if \\n(dl>\\n(CW .nr WF 1 .if (\\n(nl+\\n(.v)<=(\\n(.p+\\n(YY) .ch FO \\n(YYu .if (\\n(nl+\\n(.v)>(\\n(.p+\\n(YY) .ch FO \\n(nlu+\\n(.vu .. .\" First page footer. .de FS .ev1 .br .ll \\n(FLu .da FG .. .de FE .br .di .nr FP \\n(dn .if \\n(1T=0 .nr KI 1 \";not in abstract repeat next page. KI should be new .ev .. .de FA .if n __________________________ .if t \l'1i' .br .. .de FV .FS .nf .FY .fi .FE .. .de FX .di FY .. .de XF .ev1 .nf .ls 1 .FF .rm FF .br .ls .di .fi .ev .. .de FL .ev1 .nr FL \\$1n .ll \\$1 .ev .. .de HO Bell Laboratories Holmdel, New Jersey 07733 .. .de WH Bell Laboratories Whippany, New Jersey 07981 .. .de UL \" underline argument, don't italicize .if t \\$1\l'|0\(ul'\\$2 .if n .I \\$1 \\$2 .. .em EM . \" ACCENTS say \*'e or \*`e to get e acute or e grave .ds ' \h'\w'e'u*4/10'\z\(aa\h'-\w'e'u*4/10' .ds ` \h'\w'e'u*4/10'\z\(ga\h'-\w'e'u*4/10' . \" UMLAUT \*:u, etc. .ds : \v'-0.6m'\h'(1u-(\\n(.fu%2u))*0.13m+0.06m'\z.\h'0.2m'\z.\h'-((1u-(\\n(.fu%2u))*0.13m+0.26m)'\v'0.6m' . \" TILDE and CIRCUMFLEX .ds ^ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z^\h'|\\n:u' .ds ~ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z~\h'|\\n:u' . \" czech v symbol .ds C \\k:\\h'+\\w'e'u/4u'\\v'-0.6m'\\s6v\\s0\\v'0.6m'\\h'|\\n:u' . \" cedilla .ds , \\k:\\h'\\w'c'u*0.4u'\\z,\\h'|\\n:u' 'u*4/10'\z\(aa\h'-\w'e'u*4/10' .ds ` \h'\w'e'u*4/10'\z\(ga\h'-\w'e'u*4/10' . \" UMLAUT \*:u, etc. .ds : \v'-0.6m'\h'(1u-(\\n(.fu%2u))*0.13m+0.06m'\z.\h'0.2m'\z.\h'-((1u-(\\n(.fu%2u))*0.13m+0.26m)'\v'0.6m' . \" TILDE and CIRCUMFLEX .ds ^ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z^\h'|\\n:u' .ds ~ \\k:\h'-\. \"OK - "other keywords" for cover sheet. .de OK .br .di .di OD .nf .ft 3 .. . \"CS - spew out cover sheet .de CS .br .di .if t .po 0.5i .ds K1 \\$1 .ds K2 \\$2 .ds K3 \\$3 .ds K4 \\$4 .ds K5 \\$5 .ds K6 \\$6 .nr K1 1 .if t .sp |.5i .if t .lg .if t .ll 7.0i .nf .if t \h'7n'\s24\(bs\s12\f3 Bell Laboratories \s16\f1Cover Sheet for Technical Memorandum .if n Bell Laboratories Cover Sheet for Technical Memorandum .sp .if t \s6\l'7i' .fi .ps 9 .ft 2 .if t .sp 2p The information contained herein is for the use of employees of Bell Laboratories and is not for publication. (See GEI 13.9-3)\p .QQ...Warning: studying this document may cause drowsiness. Do not read before driving or operating machinery. (See GEI 13.9-3)\p .ft 1 .nf .if t \s6\l'7i' .sp .if t .ll 6.0i .if n .ll 30 .if t .po 1.0i .ps 9 .if t .ta 0.5i 4.5i 4.9i .if n .ta 9 39 46 .mk Title- \f3\s10 .rt .if t .in 0.5i .if n .in 10 .hy 0 .WT .hy 14 .rt .ll \\n(LLu .if t .in 4.5i .if n .in 40 \s9\f1Date- \s10\f3 .rt .if t .in 4.9i .if n .in 47 \\*(DY .sp .if t .ti 4.5i .if n .ti 40 .mk \s9\f1TM- \f3\s10 .br .rt .CT \\*(MN .in 0 .sp |\\n(.hu+1v .mk \s9\f1Other Keywords- \f3 .rt .if t .in 1.1i .if n .in 20 .OD .rm OK .rm OD .in 0 .if t .sp .7i .if n .sp 3 .ps 9 .if t .ta 1.8i 3.3i 4.3i .if n .ta 19 34 44 .ft 1 Author Location Extension Charging Case- \s10\f3\\*(CA .ps 10 .nf .mk .A1 .rt \\*(R1 \\*(E1 \f1\s9Filing Case- \s10\f3\\*(CC .if \\n(NA-1 .CB 2 .if \\n(NA-2 .CB 3 .if \\n(NA-3 .CB 4 .if \\n(NA-4 .CB 5 .ft 1 .wh 9.3i CG .if t .sp .4i .if n .sp 2 .WB .br .if 9.2i-\\n(nlu-\\n(FPu>0 .sp 9.2i-\\n(nlu-\\n(FPu .FG .rr K1 .bp 1 .rm CG .if t .po \\n(POu .. . \" CG - write bottom box on cover sheet .de CG .if t .po 0.5i .ch FO 12i .ch FX 12i .if t .ll 7i .br .if t \l'7i' .if t .ta 1.4i 2.8i 4.2i .if n .ta 14 29 44 .if t .sp 8p .if n .sp Pages Text \\*(K1 Other \\*(K2 Total \\*(K3 .if t .sp 8p .if n .sp .if t No. Figures \\*(K4 No. Tables \\*(K5 No. Refs. \\*(K6 \b'|||||\ \ ' .if n No. Figures \\*(K4 No. Tables \\*(K5 No. Refs. \\*(K6 .br .if t \l'7i' .ps 7 .br .if n .sp .rm K1 .rm K2 .rm K3 .rm K4 .rm K5 .rm K6 .if t .tl 'E-1932-U (6-73)'SEE REVERSE SIDE FOR DISTRIBUTION LIST'' .if n .tl 'E-1932-U (6-73) SEE REVERSE SIDE FOR DISTRIBUTION LIST''' .if t .po 0.5i .ll \\n(LLu .ps 10 .ch CG 12i .if \\n(K1>0 .bp .. . \"CB - help with cover sheet .de CB .br .mk .A\\$1 .rt .if \\$1-1 .if !\\$1-2 \& \\*(R2 \\*(E2 .if \\$1-2 .if !\\$1-3 \& \\*(R3 \\*(E3 .if \\$1-3 .if !\\$1-4 \& \\*(R4 \\*(E4 .if \\$1-4 .if !\\$1-5 \& \\*(R5 \\*(E5 .br .. .de CT \\$1 \\$2 \\$3 \\$4 .. . \"S1 - tm style .de S1 .br .if t .ta 4.75i .if n .ta 46 .ll 80 .ps 36 .br .if t \t\(bs .if t .vs .25i .if n .sp 24p .ps 12 .br .ft 3 .nf \tBell Laboratories .ft 1 .fi .na .ps 8 .vs 12p .sp .5i .mk .fi .ll .ll 4.0i Subject: .ft 3 .if n 'in +9 .ps .hy 0 .WT .hy 14 .ft 1 .br .if n 'in -9 .if \\n(MM>1 \\s8Case- \\*(CA\\s10 .if \\n(MM>2 --\s8 File- \\*(CC\\s10 .br .rt .if n .ll 70 .if t .ll 6.5i .if t .in 5.10i .if n .in 52 .ps 8 .mk .ti -6n date: .ps \\n(PS .ft 3 .br .rt \\*(DY .sp .ft 1 .ps 8 .mk .ti -6n from: .ps .br .rt .ft 3 .A1 .br .if \\n(NA>1 .A2 .br .if \\n(NA>2 .A3 .br .if \\n(NA>3 .A4 .br .if \\n(NA>4 .A5 .ft 1 .sp .mk .ps 8 .ti -6n .ft 1 .if \\n(IM=0 .if \\n(MM .if \\n(MN=0 TM: .if \\n(IM=0 .if \\n(MM .if \\n(MN=1 MF: .if \\n(IM=0 .if \\n(MM .if \\n(MN=2 MR: .if \\n(IM=0 .if \\n(MM .if \\n(MN=3 EN: .br .ti \\n(.iu .rt .ps .ft 3 .hy 0 .ll 10u*\w'0'u+\\n(.iu .if \\n(MM \\*(MN .hy 14 .ll .ft 1 .ll \\n(LLu .in .if \\n(IM=0 .sp .ad .ce .ft 2 .if \\n(IM=0 \\*(QF .ft 1 .ce 0 .if \\n(IM=0 .sp .ad .. from: .ps .br .rt .ft 3 .A1 .br .if \\n(NA>1 .A2 .br .if \\n(NA>2 .A3 .br .if \\n(NA>3 .A4 .br .if \\n(NA>4 .A5 .ft 1 .sp .mk .ps 8 .ti -6n .ft 1 .if \\n(IM=0 .if \\n(MM .if \\n(MN=0 TM: .if \\n(IM=0 .if \\n(MM .if \\n(MN=1 MF: .if \\n(IM=0 .if \\n(MM .if \\n(MN=2 MR: .if \\n(IM=0 .if \\n(MM .if \\n(MN=3 EN: .br .ti \\n(.iu .rt .ps .ft 3 .hy 0 .ll 10u*\w'0'u+\\n(.iu .if \\n(MM \\*(MN .hy 14 .ll .ft 1 .ll \\n(LLu .in .if \\n(IM=0 .sp .ad .ce .ft 2 .if \\n(IM=0 \\*(QF .ft 1 .ce 0 .#include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/inode.h" /* * Perform process accounting functions. */ sysacct() { extern uchar(); if (suser()) { if (u.u_arg[0]==0) { if (acctp) { plock(acctp); iput(acctp); acctp = NULL; } return; } if (acctp) { u.u_error = EBUSY; return; } u.u_dirp = u.u_arg[0]; if ((acctp = namei(&uchar, 0))==NULL) return; prele(acctp); } } /* * On exit, write a record on the accounting file. */ acct() { register struct inode *ip; register i; if ((ip=acctp)==NULL) return; plock(ip); for (i=0; ii_size0&0377; u.u_offset[1] = ip->i_size1; u.u_base = &acctbuf; u.u_count = sizeof(acctbuf); u.u_segflg = 1; u.u_error = 0; writei(ip); prele(ip); } gister struct inode *ip; register i; if ((ip=acctp)==NULL) return; plock(ip); for (i=0; ii_size0&0377; u.u_offset[1] = ip->i_size1; u.u_base = &acctbuf; u.u_count = sizeof(acctbuf); u.u_segfl# #include "../head/param.h" #include "../head/systm.h" #include "../head/filsys.h" #include "../head/conf.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/user.h" #include "../head/userx.h" /* * iinit is called once (from main) * very early in initialization. * It reads the root's super block * and initializes the current date * from the last modified date. * * panic: iinit -- cannot read the super * block. Usually because of an IO error. */ iinit() { register *cp, *bp; (*bdevsw[rootdev.d_major].d_open)(rootdev, 1); bp = bread(rootdev, 1); cp = getblk(NODEV); (*bdevsw[swapdev.d_major].d_open)(swapdev, 1); if(u.u_error) panic("iinit"); bcopy(bp->b_addr, cp->b_addr, 256); brelse(bp); mount[0].m_bufp = cp; mount[0].m_dev = rootdev; cp = cp->b_addr; cp->s_flock = 0; cp->s_ilock = 0; cp->s_ronly = 0; time = cp->s_time; } /* * alloc will obtain the next available * free disk block from the free list of * the specified device. * The super block has up to 100 remembered * free blocks; the last of these is read to * obtain 100 more . . . * * no space on dev x/y -- when * the free list is exhausted. */ alloc(dev) { int bno; register *bp, *ip, *fp; fp = getfs(dev); while(fp->s_flock) sleep(&fp->s_flock, PINOD); do { if(fp->s_nfree <= 0) goto nospace; bno = fp->s_free[--fp->s_nfree]; if(bno == 0) goto nospace; } while (badblock(fp, bno, dev)); if(fp->s_nfree <= 0) { fp->s_flock++; bp = bread(dev, bno); ip = bp->b_addr; fp->s_nfree = *ip++; bcopy(ip, fp->s_free, 100); brelse(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } bp = getblk(dev, bno); clrbuf(bp); fp->s_fmod = 1; return(bp); nospace: fp->s_nfree = 0; prdev("no space", dev); u.u_error = ENOSPC; return(NULL); } /* * place the specified disk block * back on the free list of the * specified device. */ free(dev, bno) { register *fp, *bp, *ip; fp = getfs(dev); fp->s_fmod = 1; while(fp->s_flock) sleep(&fp->s_flock, PINOD); if (badblock(fp, bno, dev)) return; if(fp->s_nfree <= 0) { fp->s_nfree = 1; fp->s_free[0] = 0; } if(fp->s_nfree >= 100) { fp->s_flock++; bp = getblk(dev, bno); ip = bp->b_addr; *ip++ = fp->s_nfree; bcopy(fp->s_free, ip, 100); fp->s_nfree = 0; bwrite(bp); fp->s_flock = 0; wakeup(&fp->s_flock); } fp->s_free[fp->s_nfree++] = bno; fp->s_fmod = 1; } /* * Check that a block number is in the * range between the I list and the size * of the device. * This is used mainly to check that a * garbage file system has not been mounted. * * bad block on dev x/y -- not in range */ badblock(afp, abn, dev) { register struct filsys *fp; register char *bn; fp = afp; bn = abn; if (bn < fp->s_isize+2 || bn >= fp->s_fsize) { prdev("bad block", dev); return(1); } return(0); } /* * Allocate an unused I node * on the specified device. * Used with file creation. * The algorithm keeps up to * 100 spare I nodes in the * super block. When this runs out, * a linear search through the * I list is instituted to pick * up 100 more. */ ialloc(dev) { register *fp, *bp, *ip; int i, j, k, ino; fp = getfs(dev); while(fp->s_ilock) sleep(&fp->s_ilock, PINOD); loop: if(fp->s_ninode > 0) { ino = fp->s_inode[--fp->s_ninode]; ip = iget(dev, ino); if (ip==NULL) return(NULL); if(ip->i_mode == 0) { for(bp = &ip->i_mode; bp < &ip->i_addr[8];) *bp++ = 0; fp->s_fmod = 1; return(ip); } /* * Inode was allocated after all. * Look some more. */ iput(ip); goto loop; } fp->s_ilock++; ino = 0; for(i=0; is_isize; i++) { bp = bread(dev, i+2); ip = bp->b_addr; for(j=0; j<256; j=+16) { ino++; if(ip[j] != 0) continue; for(k=0; ks_inode[fp->s_ninode++] = ino; if(fp->s_ninode >= 100) break; cont:; } brelse(bp); if(fp->s_ninode >= 100) break; } fp->s_ilock = 0; wakeup(&fp->s_ilock); if (fp->s_ninode > 0) goto loop; prdev("Out of inodes", dev); u.u_error = ENOSPC; return(NULL); } /* * Free the specified I node * on the specified device. * The algorithm stores up * to 100 I nodes in the super * block and throws away any more. */ ifree(dev, ino) { register *fp; fp = getfs(dev); if(fp->s_ilock) return; if(fp->s_ninode >= 100) return; fp->s_inode[fp->s_ninode++] = ino; fp->s_fmod = 1; } /* * getfs maps a device number into * a pointer to the incore super * block. * The algorithm is a linear * search through the mount table. * A consistency check of the * in core free-block and i-node * counts. * * bad count on dev x/y -- the count * check failed. At this point, all * the counts are zeroed which will * almost certainly lead to "no space" * diagnostic * panic: no fs -- the device is not mounted. * this "cannot happen" */ getfs(dev) { register struct mount *p; register char *n1, *n2; for(p = &mount[0]; p < &mount[NMOUNT]; p++) if(p->m_bufp != NULL && p->m_dev == dev) { p = p->m_bufp->b_addr; n1 = p->s_nfree; n2 = p->s_ninode; if(n1 > 100 || n2 > 100) { prdev("bad count", dev); p->s_nfree = 0; p->s_ninode = 0; } return(p); } panic("no fs"); } /* * update is the internal name of * 'sync'. It goes through the disk * queues to initiate sandbagged IO; * goes through the I nodes to write * modified nodes; and it goes through * the mount table to initiate modified * super blocks. */ update() { register struct inode *ip; register struct mount *mp; register *bp; if(updlock) return; updlock++; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp != NULL) { ip = mp->m_bufp->b_addr; if(ip->s_fmod==0 || ip->s_ilock!=0 || ip->s_flock!=0 || ip->s_ronly!=0) continue; bp = getblk(mp->m_dev, 1); ip->s_fmod = 0; ip->s_time = time; bcopy(ip, bp->b_addr, 256); bwrite(bp); } for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if((ip->i_flag&ILOCK)==0 && ip->i_count) { ip->i_flag =| ILOCK; ip->i_count++; iupdat(ip); iput(ip); } updlock = 0; bflush(NODEV); } p = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp != NULL) { ip = mp->m_bufp->b_addr; if(ip->s_fmod==0 || ip->s_ilock!=0 || ip->s_flock!=0 || ip->s_ronly!=0) continue; bp = getblk(mp->m_dev, 1); ip->s_fmod = 0; ip->s_time = time; bcopy(ip, bp->b_addr, 256); bwrite(bp); } for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if((ip->i_flag&ILOCK)==0 && ip->i_count) { ip->i_flag =| ILOCK; ip->i_count++; iupdat(i# #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/procx.h" #define UMODE 0170000 #define SCHMAG 8/10 /* * clock is called straight from * the real time clock interrupt. * * Functions: * reprime clock * copy *switches to display * implement callouts * maintain user/system times * maintain date * profile * tout wakeup (sys sleep) * lightning bolt wakeup (every second) * alarm clock signals * jab the scheduler */ char *await { &waitloc }; clock(dev, sp, r1, nps, r0, pc, ps) { register struct callo *p1, *p2; register struct proc *pp; int a; /* * restart clock */ *lks = 0115; /* * display register */ display(); /* * callouts * if none, just return * else update first non-zero time */ if(callout[0].c_func == 0) goto out; p2 = &callout[0]; while(p2->c_time<=0 && p2->c_func!=0) p2++; p2->c_time--; /* * if ps is high, just return */ if((ps&0340) != 0) goto out; /* * callout */ spl5(); if(callout[0].c_time <= 0) { p1 = &callout[0]; while(p1->c_func != 0 && p1->c_time <= 0) { (*p1->c_func)(p1->c_arg); p1++; } p2 = &callout[0]; while(p2->c_func = p1->c_func) { p2->c_time = p1->c_time; p2->c_arg = p1->c_arg; p1++; p2++; } } /* * lightning bolt time-out * and time of day */ out: a = dk_busy&07; if((ps&UMODE) == UMODE) { u.u_utime++; if(u.u_prof[3]) incupc(pc, u.u_prof); if(u.u_procp->p_nice > 2) a =+ 8; } else { a =+ 16; if (pc == await) a =+ 8; u.u_stime++; } dk_time[a] =+ 1; pp = u.u_procp; if(++pp->p_cpu == 0) pp->p_cpu--; if(++lbolt >= HZ) { if((ps&0340) != 0) return; lbolt =- HZ; ++time; spl1(); if (time == tout) wakeup(&tout); runrun++; if((time.loword&03) == 0) wakeup(&lbolt); for(pp = &proc[0]; pp < procend; pp++) if (pp->p_stat && pp->p_statp_time != 127) pp->p_time++; if(pp->p_clktim) if(--pp->p_clktim == 0) psignal(pp, SIGCLK); a = (pp->p_cpu & 0377)*SCHMAG + pp->p_nice; if(a < 0) a = 0; if(a > 255) a = 255; pp->p_cpu = a; if(pp->p_pri >= PUSER) setpri(pp); } if(runin!=0) { runin = 0; wakeup(&runin); } if((ps&UMODE) == UMODE) { u.u_ar0 = &r0; if(issig()) psig(); } } } /* * timeout is called to arrange that * fun(arg) is called in tim/HZ seconds. * An entry is sorted into the callout * structure. The time in each structure * entry is the number of HZ's more * than the previous entry. * In this way, decrementing the * first entry has the effect of * updating all entries. * * The panic is there because there is nothing * intelligent to be done if an entry won't fit. */ timeout(fun, arg, tim) { register struct callo *p1, *p2; register t; int s; t = tim; s = PS->integ; p1 = &callout[0]; spl7(); while(p1->c_func != 0 && p1->c_time <= t) { t =- p1->c_time; p1++; } if (p1 >= &callout[NCALL-1]) panic("Timeout table overflow"); p1->c_time =- t; p2 = p1; while(p2->c_func != 0) p2++; while(p2 >= p1) { (p2+1)->c_time = p2->c_time; (p2+1)->c_func = p2->c_func; (p2+1)->c_arg = p2->c_arg; p2--; } p1->c_time = t; p1->c_func = fun; p1->c_arg = arg; PS->integ = s; } g, tim) { register struct callo *p1, *p2; register t; int s; t = tim; s = PS->integ; p1 = &callout[0]; spl7(); while(p1->c_func != 0 && p1->c_time <= t) { t =- p1->c_time; p1++; } if (p1 >= &callout[NCALL-1]) panic("Timeout table overflow"); p1->c_time # #include "../head/param.h" /* * Copyright 1974 Bell Telephone Laboratories Inc */ /* * Frozen Configuration Table - New devices may be * added to the end of the tables only! * block order - rk,rp,rf,tm,tc,hp,ht,hs,0 * character order - kl,pc,lp,dc,dh,dp,dj,dn,mem,rk,rf,rp,tm, * hp,ht,hs,sys,0 */ int (*bdevsw[])() { /* 0*/ &rkopen, &nulldev, &rkstrategy, &rktab, /* 1*/ &rpopen, &nulldev, &rpstrategy, &rptab, /* 2*/ &rfopen, &nulldev, &rfstrategy, &rftab, /* 3*/ &tmopen, &tmclose, &tmstrategy, &tmtab, /* 4*/ &tcopen, &tcclose, &tcstrategy, &tctab, /* 5*/ &nodev, &nodev, &nodev, 0, /* 6*/ &nodev, &nodev, &nodev, 0, /* 7*/ &nodev, &nodev, &nodev, 0, 0 }; int (*cdevsw[])() { /* 0*/ &klopen, &klclose, &klread, &klwrite, &klsgtty, /* 1*/ &pcopen, &pcclose, &pcread, &pcwrite, &nodev, /* 2*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 3*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 4*/ &dhopen, &dhclose, &dhread, &dhwrite, &dhsgtty, /* 5*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 6*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 7*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 8*/ &nulldev, &nulldev, &mmread, &mmwrite, &nodev, /* 9*/ &nulldev, &nulldev, &rkread, &rkwrite, &nodev, /*10*/ &nulldev, &nulldev, &rfread, &rfwrite, &nodev, /*11*/ &rpopen, &nulldev, &rpread, &rpwrite, &nodev, /*12*/ &tmopen, &tmclose, &tmread, &tmwrite, &nodev, /*13*/ &nodev, &nodev,  &nodev, &nodev, &nodev, /*14*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*15*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*16*/ &nodev, &nodev, &nodev, &nodev, &nodev, 0 }; int (*ctlsw[])() { /* 0*/ &nulldev, &klmctl, /* 1*/ &nodev, &nodev, /* 2*/ &nodev, &nodev, /* 3*/ &dhparam, &dhmctl, 0 }; int (*linesw[])() { &ttopen, &ttclose, &ttread, &ttwrite, &ttyinput,&ttxmtd, &ttmt, &ttstty, &hdopen, &hdclose, &hdread, &hdwrite, &hdrcvd,&hdxmtd, &hdmt, &hdstty, 0 }; int rootdev {(1<<8)|9}; int swapdev {(2<<8)|0}; int swplo 1; int nswap 1023; int sysparam[]{ NPROC, NTEXT, NINODE, NFILE, NBUF, NMOUNT, NCLIST, 0 }; int *errtabs[] { &rketab, &rfetab, &rpetab, &tcetab, &tmetab, 0 }; / &nodev, &nodev, /* 2*/ &nodev, &nodev, /* 3*/ &dhparam, &dhmctl, 0 }; int (*linesw[])() { &ttopen, &ttclose, &ttread, &ttwrite, &ttyinput,&ttxmtd, &ttmt, &ttstty, &hdopen, &hdclose, &hdread, &hdwrite,# #include "../head/param.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/filsys.h" #include "../head/file.h" #include "../head/filex.h" #include "../head/conf.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/reg.h" #include "../head/systm.h" /* * Convert a user supplied * file descriptor into a pointer * to a file structure. * Only task is to check range * of the descriptor. */ getf(f) { register *fp, rf; rf = f; if (0<=rf && rff_inode; if(rfp->f_flag&FPIPE) { ip->i_mode =& ~(IREAD|IWRITE); wakeup(ip+1); wakeup(ip+2); } if (--rfp->f_count > 0) return; plock(ip); iput(ip); if ((ip->i_mode&IFMT) == IFCHR) cfunc = cdevsw[ip->i_addr[0].d_major].d_close; else if ((ip->i_mode&IFMT)== IFBLK) cfunc = bdevsw[ip->i_addr[0].d_major].d_close; else return; flag = rfp->f_flag&(FWRITE|FREAD); for (rfp=file; rfp < &file[NFILE]; rfp++) if (rfp->f_count && rfp->f_inode==ip) return; (*cfunc)(ip->i_addr[0], flag); } /* * openi called to allow handler * of special files to initialize and * validate before actual IO. * Called on all sorts of opens * and also on mount. */ openi(ip, rw) int *ip; { register *rip; register dev, maj; rip = ip; dev = rip->i_addr[0]; maj = rip->i_addr[0].d_major & 0377; switch(rip->i_mode&IFMT) { case IFCHR: if(maj >= nchrdev) goto bad; (*cdevsw[maj].d_open)(dev, rw); break; case IFBLK: if(maj >= nblkdev) goto bad; (*bdevsw[maj].d_open)(dev, rw); } return; bad: u.u_error = ENXIO; } /* * Check mode permission on inode pointer. * Mode is READ, WRITE or EXEC. * In the case of WRITE, the * read-only status of the file * system is checked. * Also in WRITE, prototype text * segments cannot be written. * The mode is shifted to select * the owner/group/other fields. * The super user is granted all * permissions. */ access(aip, mode) int *aip; { register *ip, m; ip = aip; m = mode; if(m == IWRITE) { if(getfs(ip->i_dev)->s_ronly != 0) { u.u_error = EROFS; return(1); } if(ip->i_flag & ITEXT) { u.u_error = ETXTBSY; return(1); } } if(u.u_uid == 0) return(0); if(u.u_uid != ip->i_uid) { m =>> 3; if(u.u_gid != ip->i_gid) m =>> 3; } if((ip->i_mode&m) != 0) return(0); bad: u.u_error = EACCES; return(1); } /* * Look up a pathname and test if * the resultant inode is owned by the * current user. * If not, try for super-user. * If permission is granted, * return inode pointer. */ owner() { register struct inode *ip; extern uchar(); if ((ip = namei(uchar, 0)) == NULL) return(NULL); if(u.u_uid == ip->i_uid) return(ip); if (suser()) return(ip); iput(ip); return(NULL); } /* * Test if the current user is the * super user. */ suser() { if(u.u_uid == 0) return(1); u.u_error = EPERM; return(0); } /* * Allocate a user file descriptor. */ ufalloc(i) register i; { for (; if_count==0) { u.u_ofile[i] = fp; fp->f_count++; fp->f_offset[0] = 0; fp->f_offset[1] = 0; return(fp); } printf("no file\n"); u.u_error = ENFILE; return(NULL); } a user file descriptor * and a file structure. * Initialize the descriptor * to point at the file structure. * * no file -- if there are no available * file structures. */ falloc() { register struct file *fp; register i; if ((i = ufalloc(0)) < 0) return(NULL); for (fp = &file[0]; fp < &file[NFILE]; fp++) if (fp->f_count==0) { u.u_ofile[i] = fp; fp->f_count++; # #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/filsys.h" #include "../head/conf.h" #include "../head/buf.h" #include "../head/bufx.h" /* * Look up an inode by device,inumber. * If it is in core (in the inode structure), * honor the locking protocol. * If it is not in core, read it in from the * specified device. * If the inode is mounted on, perform * the indicated indirection. * In all cases, a pointer to a locked * inode structure is returned. * * printf warning: no inodes -- if the inode * structure is full * panic: no imt -- if the mounted file * system is not in the mount table. * "cannot happen" */ iget(dev, ino) { register struct inode *p; register *ip2; int *ip1; register struct mount *ip; loop: ip = NULL; for(p = &inode[0]; p < &inode[NINODE]; p++) { if(dev==p->i_dev && ino==p->i_number) { if((p->i_flag&ILOCK) != 0) { p->i_flag =| IWANT; sleep(p, PINOD); goto loop; } if((p->i_flag&IMOUNT) != 0) { for(ip = &mount[0]; ip < &mount[NMOUNT]; ip++) if(ip->m_inodp == p) { dev = ip->m_dev; ino = ROOTINO; goto loop; } panic("no imt"); } p->i_count++; p->i_flag =| ILOCK; return(p); } if(ip==NULL && p->i_count==0) ip = p; } if((p=ip) == NULL) { printf("Inode table overflow\n"); u.u_error = ENFILE; return(NULL); } p->i_dev = dev; p->i_number = ino; p->i_flag = ILOCK; p->i_count++; p->i_lastr = -1; ip = bread(dev, ldiv(ino+31,16)); /* * Check I/O errors */ if (ip->b_flags&B_ERROR) { brelse(ip); iput(p); return(NULL); } ip1 = ip->b_addr + 32*lrem(ino+31, 16); ip2 = &p->i_mode; while(ip2 < &p->i_addr[8]) *ip2++ = *ip1++; brelse(ip); return(p); } /* * Decrement reference count of * an inode structure. * On the last reference, * write the inode out and if necessary, * truncate and deallocate the file. */ iput(p) struct inode *p; { register *rp; rp = p; if(rp->i_count == 1) { rp->i_flag =| ILOCK; if(rp->i_nlink <= 0) { itrunc(rp); rp->i_mode = 0; rp->i_flag =| IUPD; ifree(rp->i_dev, rp->i_number); } iupdat(rp); prele(rp); rp->i_flag = 0; rp->i_number = 0; } rp->i_count--; prele(rp); } /* * Check accessed and update flags on * an inode structure. * If either is on, update the inode * with the current time. */ iupdat(p) int *p; { register *ip1, *ip2, *rp; int *bp, i; rp = p; if((rp->i_flag&(IUPD|IACC)) != 0) { if(getfs(rp->i_dev)->s_ronly) return; i = rp->i_number+31; bp = bread(rp->i_dev, ldiv(i,16)); ip1 = bp->b_addr + 32*lrem(i, 16); ip2 = &rp->i_mode; while(ip2 < &rp->i_addr[8]) *ip1++ = *ip2++; if(rp->i_flag&IACC) { *ip1++ = time.hiword; *ip1++ = time.loword; } else ip1 =+ 2; if(rp->i_flag&IUPD) { *ip1++ = time.hiword; *ip1++ = time.loword; } rp->i_flag =& ~(IUPD|IACC); bdwrite(bp); } } /* * Free all the disk blocks associated * with the specified inode structure. * The blocks of the file are removed * in reverse order. This FILO * algorithm will tend to maintain * a contiguous free list much longer * than FIFO. */ itrunc(ip) int *ip; { register *rp, *bp, *cp; int *dp, *ep; rp = ip; if((rp->i_mode&(IFCHR&IFBLK)) != 0) return; for(ip = &rp->i_addr[7]; ip >= &rp->i_addr[0]; ip--) if(*ip) { if((rp->i_mode&ILARG) != 0) { bp = bread(rp->i_dev, *ip); for(cp = bp->b_addr+510; cp >= bp->b_addr; cp--) if(*cp) { free(rp->i_dev, *cp); } brelse(bp); } free(rp->i_dev, *ip); *ip = 0; } rp->i_mode =& ~ILARG; rp->i_size0 = 0; rp->i_size1 = 0; rp->i_flag =| IUPD; } /* * Make a new file. */ maknode(mode) { register *ip; ip = ialloc(u.u_pdir->i_dev); if (ip==NULL) { iput(u.u_pdir); return(NULL); } ip->i_flag =| IACC|IUPD; ip->i_mode = mode|IALLOC; ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; wdir(ip); return(ip); } /* * Write a directory entry with * parameters left as side effects * to a call to namei. */ wdir(ip) int *ip; { register char *cp1, *cp2; u.u_dent.u_ino = ip->i_number; cp1 = &u.u_dent.u_name[0]; for(cp2 = &u.u_dbuf[0]; cp2 < &u.u_dbuf[DIRSIZ];) *cp1++ = *cp2++; u.u_count = DIRSIZ+2; u.u_segflg = 1; u.u_base = &u.u_dent; writei(u.u_pdir); iput(u.u_pdir); } _flag =| IACC|IUPD; ip->i_mode = mode|IALLOC; ip->i_nlink = 1; ip->i_uid = u.u_uid; ip->i_gid = u.u_gid; wdir(ip); return(ip); } /* * Write a directory entry with * parameters left as side effects * to a call to namei./ Copyright 1974 Bell Telephone Laboratories Inc / low core .data br4 = 200 br5 = 240 br6 = 300 br7 = 340 . = 0^. br 1f 4 / trap vectors trap; br7+0. / bus error trap; br7+1. / illegal instruction trap; br7+2. / bpt-trace trap trap; br7+3. / iot trap trap; br7+4. / power fail trap; br7+5. / emulator trap trap; br7+6. / system entry . = 40^. .globl start, dump 1: jmp start jmp dump . = 50^. stray; br7+10. stray; br7+11. . = 60^. klin; br5 klou; br5 . = 70^. pcin; br4 pcou; br4  . = 100^. kwlp; br6 . = 104^. kwlp; br6 . = 110^. stray; br7+2. stray; br7+3. stray; br7+4. stray; br7+5. stray; br7+6. stray; br7+7. stray; br7+8. stray; br7+9. stray; br7+10. stray; br7+11. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. stray; br7+0. . = 204^. rfio; br5 . = 210^. stray; br7+2. . = 214^. tcio; br6 . = 220^. rkio; br5 . = 224^. tmio; br5 . = 230^. stray; br7+6. stray; br7+7. . = 240^. trap; br7+7. / programmed interrupt trap; br7+8. / floating point trap; br7+9. / segmentation violation . = 254^. rpio; br5 . = 260^. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. / floating vectors . = 300^. dmin; br5+0. . = 304^. stray; br7+1. . = 310^. dhin; br5+0. dhou; br5+0. . = 320^. stray; br7+4. stray; br7+5. stray; br7+6. stray; br7+7. stray; br7+8. stray; br7+9. stray; br7+10. stray; br7+11. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. stray; br7+0. ////////////////////////////////////////////////////// / interface code to C ////////////////////////////////////////////////////// .globl call, trap .globl _klrint klin: jsr r0,call; _klrint .globl _klxint klou: jsr r0,call; _klxint .globl _pcrint pcin: jsr r0,call; _pcrint .globl _pcpint pcou: jsr r0,call; _pcpint .globl _clock kwlp: jsr r0,call; _clock .globl _rfintr rfio: jsr r0,call; _rfintr .globl _tcintr tcio: jsr r0,call; _tcintr .globl _rkintr rkio: jsr r0,call; _rkintr .globl _tmintr tmio: jsr r0,call; _tmintr .globl _rpintr rpio: jsr r0,call; _rpintr .globl _dmint dmin: jsr r0,call; _dmint .globl _dhrint dhin: jsr r0,call; _dhrint .globl _dhxint dhou: jsr r0,call; _dhxint .globl _stray stray: jsr r0,call; _stray t .globl _pcrint pcin: jsr r0,call; _pcrint .globl _pcpint pcou: jsr r0,call; _pcpint .globl _clock kwlp: jsr r0,call; _clock .globl _rfintr rfio: jsr r0,call; _rfintr .globl _tcintr tcio: jsr r0,call; _tcintr .globl _rkintr rkio: jsr r0,call; _rkintr .globl _tmintr tmio: jsr r0,call; _tmintr .globl _rpintr rpi/ machine language assist / for 11/40 .mt = 1 /1 = tm11 0 = tju16 / non-UNIX instructions mfpi = 6500^tst mtpi = 6600^tst wait = 1 rtt = 6 reset = 5 .globl trap, call .globl _trap trap: mov PS,-4(sp) tst nofault bne 1f mov SSR0,ssr mov SSR2,ssr+4 mov $1,SSR0 jsr r0,call1; _trap / no return 1: mov $1,SSR0 mov nofault,(sp) rtt .globl _runrun, _qswtch call1: tst -(sp) bic $340,PS br 1f call: mov PS,-(sp) 1: mov r1,-(sp) mfpi sp mov 4(sp),-(sp) bic $!37,(sp) bit $30000,PS beq 1f jsr pc,*(r0)+ 2: bis $340,PS tstb _runrun beq 2f bic $340,PS jsr pc,_qswtch br 2b 2: tst (sp)+ mtpi sp br 2f 1: bis $30000,PS jsr pc,*(r0)+ cmp (sp)+,(sp)+ 2: mov (sp)+,r1 tst (sp)+ mov (sp)+,r0 rtt .globl _savfp, _display _savfp: _display: rts pc .globl _incupc _incupc: mov r2,-(sp) mov 6(sp),r2 / base of prof with base,leng,off,scale mov 4(sp),r0 / pc sub 4(r2),r0 / offset clc ror r0 mul 6(r2),r0 / scale ashc $-14.,r0 inc r1 bic $1,r1 cmp r1,2(r2) / length bhis 1f add (r2),r1  / base mov nofault,-(sp) mov $2f,nofault mfpi (r1) inc (sp) mtpi (r1) br 3f 2: clr 6(r2) 3: mov (sp)+,nofault 1: mov (sp)+,r2 rts pc / Character list get/put .globl _getc, _putc .globl _cfreelist _getc: mov 2(sp),r1 mov PS,-(sp) mov r2,-(sp) bis $340,PS bic $40,PS / spl 6 mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ / count bne 1f clr (r1)+ clr (r1)+ / last block br 2f 1: bit $7,r2 bne 3f mov -10(r2),(r1) / next block add $2,(r1) 2: dec r2 bic $7,r2 mov _cfreelist,(r2) mov r2,_cfreelist 3: mov (sp)+,r2 mov (sp)+,PS rts pc 9: clr 4(r1) mov $-1,r0 mov (sp)+,r2 mov (sp)+,PS rts pc _putc: mov 2(sp),r0 mov 4(sp),r1 mov PS,-(sp) mov r2,-(sp) mov r3,-(sp) bis $340,PS bic $40,PS / spl 6 mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist clr (r2)+ mov r2,2(r1) / first ptr br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3 beq 9f mov (r3),_cfreelist mov r3,-10(r2) mov r3,r2 clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) / count clr r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc 9: mov pc,r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc .globl _backup .globl _regloc _backup: mov 2(sp),ssr+2 mov r2,-(sp) jsr pc,backup mov r2,ssr+2 mov (sp)+,r2 movb jflg,r0 bne 2f mov 2(sp),r0 movb ssr+2,r1 jsr pc,1f movb ssr+3,r1 jsr pc,1f movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 2: rts pc 1: mov r1,-(sp) asr (sp) asr (sp) asr (sp) bic $!7,r1 movb _regloc(r1),r1 asl r1 add r0,r1 sub (sp)+,(r1) rts pc / hard part / simulate the ssr2 register missing on 11/40 backup: clr r2 / backup register ssr1 mov $1,bflg / clrs jflg mov ssr+4,r0 jsr pc,fetch mov r0,r1 ash $-11.,r0 bic $!36,r0 jmp *0f(r0) 0: t00; t01; t02; t03; t04; t05; t06; t07 t10; t11; t12; t13; t14; t15; t16; t17 t00: clrb bflg t10: mov r1,r0 swab r0 bic $!16,r0 jmp *0f(r0) 0: u0; u1; u2; u3; u4; u5; u6; u7 u6: / single op, m[tf]pi, sxt, illegal bit $400,r1 beq u5 / all but m[tf], sxt bit $200,r1 beq 1f / mfpi bit $100,r1 bne u5 / sxt / simulate mtpi with double (sp)+,dd bic $4000,r1 / turn instr into (sp)+ br t01 / simulate mfpi with double ss,-(sp) 1: ash $6,r1 bis $46,r1 / -(sp) br t01 u4: / jsr mov r1,r0 jsr pc,setreg / assume no fault bis $173000,r2 / -2 from sp rts pc t07: / EIS clrb bflg u0: / jmp, swab u5: / single op mov r1,r0 br setreg t01: / mov t02: / cmp t03: / bit t04: / bic t05: / bis t06: / add t16: / sub clrb bflg t11: / movb t12: / cmpb t13: / bitb t14: / bicb t15: / bisb mov r1,r0 ash $-6,r0 jsr pc,setreg swab r2 mov r1,r0 jsr pc,setreg / if delta(dest) is zero, / no need to fetch source bit $370,r2 beq 1f / if mode(source) is R, / no fault is possible bit $7000,r1 beq 1f / if reg(source) is reg(dest), / too bad. mov r2,-(sp) bic $174370,(sp) cmpb 1(sp),(sp)+ beq t17 / start source cycle / pick up value of reg mov r1,r0 ash $-6,r0 bic $!7,r0 movb _regloc(r0),r0 asl r0 add ssr+2,r0 mov (r0),r0 / if reg has been incremented, / must decrement it before fetch bit $174000,r2 ble 2f dec r0 bit $10000,r2 beq 2f dec r0 2: / if mode is 6,7 fetch and add X(R) to R bit $4000,r1 beq 2f bit $2000,r1 beq 2f mov r0,-(sp) mov ssr+4,r0 add $2,r0 jsr pc,fetch add (sp)+,r0 2: / fetch operand / if mode is 3,5,7 fetch * jsr pc,fetch bit $1000,r1 beq 1f bit $6000,r1 bne fetch 1: rts pc t17: / illegal u1: / br u2: / br u3: / br u7: / illegal incb jflg rts pc setreg: mov r0,-(sp) bic $!7,r0 bis r0,r2 mov (sp)+,r0 ash $-3,r0 bic $!7,r0 movb 0f(r0),r0 tstb bflg beq 1f bit $2,r2 beq 2f bit $4,r2 beq 2f 1: cmp r0,$20 beq 2f cmp r0,$-20 beq 2f asl r0 2: bisb r0,r2 rts pc 0: .byte 0,0,10,20,-10,-20,0,0 fetch: bic $1,r0 mov nofault,-(sp) mov $1f,nofault mfpi (r0) mov (sp)+,r0 mov (sp)+,nofault rts pc 1: mov (sp)+,nofault clrb r2 / clear out dest on fault mov $-1,r0 rts pc .bss bflg: .=.+1 jflg: .=.+1 .text .globl _fubyte, _subyte .globl _fuibyte, _suibyte .globl _fuword, _suword .globl _fuiword, _suiword _fuibyte: _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword cmp r1,2(sp) beq 1f swab r0 1: bic $!377,r0 rts pc _suibyte: _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,pword clr r0 rts pc _fuiword: _fuword: mov 2(sp),r1 fuword: jsr pc,gword rts pc gword: mov PS,-(sp) bis $340,PS mov nofault,-(sp) mov $err,nofault mfpi (r1) mov (sp)+,r0 br 1f _suiword: _suword: mov 2(sp),r1 mov 4(sp),r0 suword: jsr pc,pword rts pc pword: mov PS,-(sp) bis $340,PS mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpi (r1) 1: mov (sp)+,nofault mov (sp)+,PS rts pc err: mov (sp)+,nofault mov (sp)+,PS tst (sp)+ mov $-1,r0 rts pc .globl _copyin, _copyout .globl _copyiin, _copyiout _copyiin: _copyin: jsr pc,copsu 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyiout: _copyout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpi (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 14(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc .globl _idle, _waitloc _idle: mov PS,-(sp) bic $340,PS wait _waitloc: mov (sp)+,PS rts pc .globl _savu, _retu, _aretu _savu: bis $340,PS mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ bic $340,PS jmp (r1) _aretu: bis $340,PS mov (sp)+,r1 mov (sp),r0 br 1f _retu: bis $340,PS mov (sp)+,r1 mov (sp),KISA6 mov $_u,r0 1: mov (r0)+,sp mov (r0)+,r5 bic $340,PS jmp (r1) .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: bic $340,PS rts pc _spl1: bis $40,PS bic $300,PS rts pc _spl4: _spl5: bis $340,PS bic $100,PS rts pc _spl6: bis $340,PS bic $40,PS rts pc _spl7: bis $340,PS rts pc .globl _copyseg _copyseg: mov PS,-(sp) mov UISA0,-(sp) mov UISA1,-(sp) mov $30340,PS mov 10(sp),UISA0 mov 12(sp),UISA1 mov UISD0,-(sp) mov UISD1,-(sp) mov $6,UISD0 mov $6,UISD1 mov r2,-(sp) clr r0 mov $8192.,r1 mov $32.,r2 1: mfpi (r0)+ mtpi (r1)+ sob r2,1b mov (sp)+,r2 mov (sp)+,UISD1 mov (sp)+,UISD0 mov (sp)+,UISA1 mov (sp)+,UISA0 mov (sp)+,PS rts pc .globl _clearseg _clearseg: mov PS,-(sp) mov UISA0,-(sp) mov $30340,PS mov 6(sp),UISA0 mov UISD0,-(sp) mov $6,UISD0 clr r0 mov $32.,r1 1: clr -(sp) mtpi (r0)+ sob r1,1b mov (sp)+,UISD0 mov (sp)+,UISA0 mov (sp)+,PS rts pc .globl _dpadd _dpadd: mov 2(sp),r0 add 4(sp),2(r0) adc (r0) rts pc .globl _dpcmp _dpcmp: mov 2(sp),r0 mov 4(sp),r1 sub 6(sp),r0 sub 8(sp),r1 sbc r0 bge 1f cmp r0,$-1 bne 2f cmp r1,$-512. bhi 3f 2: mov $-512.,r0 rts pc 1: bne 2f cmp r1,$512. blo 3f 2: mov $512.,r1 3: mov r1,r0 rts pc .globl dump dump: bit $1,SSR0 bne dump / save regs r0,r1,r2,r3,r4,r5,r6,KIA6 / starting at abs location 4 mov r0,4 mov $6,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ mov KISA6,(r0)+ / dump all of core (ie to first mt error) / onto mag tape. (9 track or 7 track 'binary') .if .mt mov $MTC,r0 mov $60004,(r0)+ clr 2(r0) 1: mov $-512.,(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset mov $60007,-(r0) br . .endif .if .mt-1 mov $TUC,r0 mov $60,(r0)+ clr 2(r0) clr 6(r0) mov $1300,24.(r0) / 800 bpi, pdp11 mode, unit zero 1: mov $-256.,(r0) mov $512.,4(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset mov $027,-(r0) br . .endif .globl start, _end, _edata, _main start: bit $1,SSR0 bne start / loop if restart reset / Set loc. 0 to trap to system, in case of / hardware glitch mov $trap,0 mov $340+15.,2 / initialize systems segments mov $KISA0,r0 mov $KISD0,r1 mov $200,r4 clr r2 mov $6,r3 1: mov r2,(r0)+ mov $77406,(r1)+ / 4k rw add r4,r2 sob r3,1b / initialize user segment mov $_end+63.,r2 ash $-6,r2 bic $!1777,r2 mov r2,(r0)+ / ksr6 = sysu mov $usize-1\<8|6,(r1)+ / initialize io segment / set up counts on supervisor segments mov $IO,(r0)+ mov $77406,(r1)+ / rw 4k / get a sp and start segmentation mov $_u+[usize*64.],sp inc SSR0 / clear bss mov $_edata,r0 1: clr (r0)+ cmp r0,$_end blo 1b / clear user block mov $_u,r0 1: clr (r0)+ cmp r0,$_u+[usize*64.] blo 1b / set up previous mode and call main / on return, enter user mode at 0R mov $30000,PS jsr pc,_main mov $170000,-(sp) clr -(sp) rtt .globl _ldiv _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc .globl _lrem _lrem: clr r0 mov 2(sp),r1  div 4(sp),r0 mov r1,r0 rts pc .globl _lshift _lshift: mov 2(sp),r1 mov (r1)+,r0 mov (r1),r1 ashc 4(sp),r0 mov r1,r0 rts pc .globl csv csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) .globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc .globl _u _u = 140000 usize = 16. PS = 177776 SSR0 = 177572 SSR2 = 177576 KISA0 = 172340 KISA6 = 172354 KISD0 = 172300 MTC = 172522 TUC = 172440 UISA0 = 177640 UISA1 = 177642 UISD0 = 177600 UISD1 = 177602 IO = 7600 .data .globl _ka6, _cputype _ka6: KISA6 _cputype:40. .bss .globl nofault, ssr, badtrap nofault:.=.+2 ssr: .=.+6 badtrap:.=.+2 .globl _mapalloc .globl _msginit .globl _serrlog .globl _lflags globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc .globl _u _u = 140000 usize = 16. PS = 177776 SSR0 = 177572 SSR2 = 177576 KISA0 = 172340 KISA6 = 172354 KISD0 = 172300 MTC = 172522 TUC = 172440 UISA0 = 177640 UISA1 = 177642 UIS/ machine language assist / set up for 11-45 I and D space .fpp = 1 .mt = 1 /1 = tm11 0 = tju16 / non-UNIX instructions mfpi = 6500^tst mtpi = 6600^tst mfpd = 106500^tst mtpd = 106600^tst spl = 230 .if .fpp ldfps = 170100^tst stfps = 170200^tst .endif wait = 1 rtt = 6 reset = 5 HIPRI = 300 HIGH = 6 / Mag tape dump / save registers in low core and / write all core onto mag tape. / entry is thru 44 abs .data .globl dump dump: bit $1,SSR0 bne dump / save regs r0,r1,r2,r3,r4,r5,r6,KIA6 / starting at abs location 4 mov r0,4 mov $6,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ mov KDSA6,(r0)+ / dump all of core (ie to first mt error) / onto mag tape. (9 track or 7 track 'binary') .if .mt mov $MTC,r0 mov $60004,(r0)+ clr 2(r0) 1: mov $-512.,(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset / end of file and loop mov $60007,-(r0) br . .endif .if .mt-1 mov $TUC,r0 mov $60,(r0)+ clr 2(r0) clr 6(r0) mov $1300,24.(r0) / 800 bpi + pdp11 mode + unit zero 1: mov $-256.,(r0) mov $-512.,4(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset mov $027,-(r0) br . .endif .globl start, _end, _edata, _etext, _main / 11/45 and 11/70 startup. / entry is thru 0 abs. / since core is shuffled, / this code can be executed but once start: inc $-1 bne . reset / Set loc. 0 to trap to system, in case of / hardware glitch mov $trap,0 / in case of bad trap through 0 mov $340+15.,2 / high pri, trap type 15 clr PS / set KI0 to physical 0  mov $77406,r3 mov $KISA0,r0 mov $KISD0,r1 clr (r0)+ mov r3,(r1)+ / set KI1-6 to eventual text resting place mov $_end+63.,r2 ash $-6,r2 bic $!1777,r2 1: mov r2,(r0)+ mov r3,(r1)+ add $200,r2 cmp r0,$KISA7 blos 1b / set KI7 to IO seg for escape mov $IO,-(r0) / set KD0-7 to physical mov $KDSA0,r0 mov $KDSD0,r1 clr r2 1: mov r2,(r0)+ mov r3,(r1)+ add $200,r2 cmp r0,$KDSA7 blos 1b / initialization / get a temp (1-word) stack / turn on segmentation / copy text to I space / clear bss in D space mov $stk+2,sp mov $05,SSR3 / 18-bit, K+U sep i and d inc SSR0 mov $_etext+100,r2 mov $_edata+100,r1 add $_etext-8192.,r1 1: mov -(r1),-(sp) mtpi -(r2) cmp r1,$_edata bhi 1b 1: clr (r1)+ cmp r1,$_end blo 1b / use KI escape to set KD7 to IO seg / set KD6 to first available core mov $IO,-(sp) mtpi *$KDSA7 mov $_etext-8192.+63.,r2 ash $-6,r2 bic $!1777,r2 add KISA1,r2 mov r2,KDSA6 mov $usize-1,$KDSD6+1 / Turn off write permission on kernel text / Take stuff above data out of address space mov $KISD0,r0 1: mov $77402,(r0)+ cmp r0,$KISD7 blo 1b mov $_end+63.,r0 ash $-6,r0 bic $!1777,r0 mov $KDSD0,r1 1: cmp r0,$200 bge 2f dec r0 bge 4f clr (r1) br 3f 4: movb r0,1(r1) br 3f 2: movb $177,1(r1) 3: tst (r1)+ sub $200,r0 cmp r1,$KDSD5 blos 1b / set up supervisor D registers mov $6,SISD0 mov $6,SISD1 / set up real sp / clear user block mov $_u+[usize*64.],sp mov $_u,r0 1: clr (r0)+ cmp r0,sp blo 1b / set up previous mode and call main / on return, enter user mode at 0R mov $30000,PS jsr pc,_main mov $170000,-(sp) clr -(sp) rtt .globl trap, call .globl _trap / all traps and interrupts are / vectored thru this routine. trap: mov PS,saveps tst nofault bne 1f mov SSR0,ssr mov SSR1,ssr+2 mov SSR2,ssr+4 mov $1,SSR0 jsr r0,call1; _trap / no return 1: mov $1,SSR0 mov nofault,(sp) rtt .text .globl _runrun, _qswtch call1: mov saveps,-(sp) spl 0 br 1f call: mov PS,-(sp) 1: mov r1,-(sp) mfpd sp mov 4(sp),-(sp) bic $!37,(sp) bit $30000,PS beq 1f .if .fpp mov $20,_u+4 / FP maint mode .endif jsr pc,*(r0)+ 2: spl HIGH tstb _runrun beq 2f spl 0 jsr pc,_savfp jsr pc,_qswtch br 2b 2: .if .fpp mov $_u+4,r1 bit $20,(r1) bne 2f mov (r1)+,r0 ldfps r0 movf (r1)+,fr0 movf (r1)+,fr1 movf fr1,fr4 movf (r1)+,fr1 movf fr1,fr5 movf (r1)+,fr1 movf (r1)+,fr2 movf (r1)+,fr3 ldfps r0 2: .endif tst (sp)+ mtpd sp br 2f 1: bis $30000,PS jsr pc,*(r0)+ cmp (sp)+,(sp)+ 2: mov (sp)+,r1 tst (sp)+ mov (sp)+,r0 rtt .globl _savfp _savfp: .if .fpp mov $_u+4,r1 bit $20,(r1) beq 1f stfps (r1)+ movf fr0,(r1)+ movf fr4,fr0 movf fr0,(r1)+ movf fr5,fr0 movf fr0,(r1)+ movf fr1,(r1)+ movf fr2,(r1)+ movf fr3,(r1)+ 1: .endif rts pc .globl _incupc _incupc: mov r2,-(sp) mov 6(sp),r2 / base of prof with base,leng,off,scale mov 4(sp),r0 / pc sub 4(r2),r0 / offset clc ror r0 mul 6(r2),r0 / scale ashc $-14.,r0 inc r1 bic $1,r1 cmp r1,2(r2) / length bhis 1f add (r2),r1 / base mov nofault,-(sp) mov $2f,nofault mfpd (r1) inc (sp) mtpd (r1) br 3f 2: clr 6(r2) 3: mov (sp)+,nofault 1: mov (sp)+,r2 rts pc .globl _display _display: dec dispdly bge 2f clr dispdly mov PS,-(sp) mov $HIPRI,PS mov CSW,r1 bit $1,r1 beq 1f bis $30000,PS dec r1 1: jsr pc,fuword mov r0,CSW mov (sp)+,PS cmp r0,$-1 bne 2f mov $120.,dispdly / 2 sec delay after CSW fault 2: rts pc / Character list get/put .globl _getc, _putc .globl _cfreelist _getc: mov 2(sp),r1 mov PS,-(sp) mov r2,-(sp) spl 6 mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ / count bne 1f clr (r1)+ clr (r1)+ / last block br 2f 1: bit $7,r2 bne 3f mov -10(r2),(r1) / next block add $2,(r1) 2: dec r2 bic $7,r2 mov _cfreelist,(r2) mov r2,_cfreelist 3: mov (sp)+,r2 mov (sp)+,PS rts pc 9: clr 4(r1) mov $-1,r0 mov (sp)+,r2 mov (sp)+,PS rts pc _putc: mov 2(sp),r0 mov 4(sp),r1 mov PS,-(sp) mov r2,-(sp) mov r3,-(sp) spl 6 mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist clr (r2)+ mov r2,2(r1) / first ptr br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3 beq 9f mov (r3),_cfreelist mov r3,-10(r2) mov r3,r2 clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) / count clr r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc 9: mov pc,r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc .globl _backup .globl _regloc _backup: mov 2(sp),r0 movb ssr+2,r1 jsr pc,1f movb ssr+3,r1 jsr pc,1f movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 2: rts pc 1: mov r1,-(sp) asr (sp) asr (sp) asr (sp) bic $!7,r1 movb _regloc(r1),r1 asl r1 add r0,r1 sub (sp)+,(r1) rts pc .globl _fubyte, _subyte .globl _fuword, _suword .globl _fuibyte, _suibyte .globl _fuiword, _suiword _fuibyte: mov 2(sp),r1 bic $1,r1 jsr pc,giword br 2f _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword 2: cmp r1,2(sp) beq 1f swab r0 1: bic $!377,r0 rts pc _suibyte: mov 2(sp),r1 bic $1,r1 jsr pc,giword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,piword clr r0 rts pc _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,pword clr r0 rts pc _fuiword: mov 2(sp),r1 fuiword: jsr pc,giword rts pc _fuword: mov 2(sp),r1 fuword: jsr pc,gword rts pc giword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mfpi (r1) mov (sp)+,r0 br 1f gword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mfpd (r1) mov (sp)+,r0 br 1f _suiword: mov 2(sp),r1 mov 4(sp),r0 suiword: jsr pc,piword rts pc _suword: mov 2(sp),r1 mov 4(sp),r0 suword: jsr pc,pword rts pc piword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpi (r1) br 1f pword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpd (r1) 1: mov (sp)+,nofault mov (sp)+,PS rts pc err: mov (sp)+,nofault mov (sp)+,PS tst (sp)+ mov $-1,r0 rts pc .globl _copyin, _copyout .globl _copyiin, _copyiout _copyiin: jsr pc,copsu 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyin: jsr pc,copsu 1: mfpd (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyiout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpi (r1)+ sob r2,1b br 2f _copyout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpd (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 14(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc .globl _idle, _waitloc _idle: mov PS,-(sp) spl 0 wait _waitloc: mov (sp)+,PS rts pc .globl _savu, _retu, _aretu _savu: spl HIGH mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ spl 0 jmp (r1) _aretu: spl 7 mov (sp)+,r1 mov (sp),r0 br 1f _retu: spl 7 mov (sp)+,r1 mov (sp),KDSA6 mov $_u,r0 1: mov (r0)+,sp mov (r0)+,r5 spl 0 jmp (r1) .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: spl 0 rts pc _spl1: spl 1 rts pc _spl4: spl 4 rts pc _spl5: spl 5 rts pc _spl6: spl 6 rts pc _spl7: spl HIGH rts pc .globl _copyseg _copyseg: mov PS,-(sp) mov 4(sp),SISA0 mov 6(sp),SISA1 mov $10000+HIPRI,PS mov r2,-(sp) clr r0 mov $8192.,r1 mov $32.,r2 1: mfpd (r0)+ mtpd (r1)+ sob r2,1b mov (sp)+,r2 mov (sp)+,PS rts pc .globl _clearseg _clearseg: mov PS,-(sp) mov 4(sp),SISA0 mov $10000+HIPRI,PS clr r0 mov $32.,r1 1: clr -(sp) mtpd (r0)+ sob r1,1b mov (sp)+,PS rts pc .globl _dpadd _dpadd: mov 2(sp),r0 add 4(sp),2(r0) adc (r0) rts pc .globl _dpcmp _dpcmp: mov 2(sp),r0 mov 4(sp),r1 sub 6(sp),r0 sub 8(sp),r1 sbc r0 bge 1f cmp r0,$-1 bne 2f cmp r1,$-512. bhi 3f 2: mov $-512.,r0 rts pc 1: bne 2f cmp r1,$512. blo 3f 2: mov $512.,r1 3: mov r1,r0 rts pc .globl _ldiv _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc .globl _lrem _lrem: clr r0 mov 2(sp),r1 div 4(sp),r0 mov r1,r0 rts pc .globl _lshift _lshift: mov 2(sp),r1 mov (r1)+,r0 mov (r1),r1 ashc 4(sp),r0 mov r1,r0 rts pc .globl csv csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) .globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc .globl _u _u = 140000 usize = 16. CSW = 177570 PS = 177776 SSR0 = 177572 SSR1 = 177574 SSR2 = 177576 SSR3 = 172516 KISA0 = 172340 KISA1 = 172342 KISA7 = 172356 KISD0 = 172300 KISD7 = 172316 KDSA0 = 172360 KDSA6 = 172374 KDSA7 = 172376 KDSD0 = 172320 KDSD5 = 172332 KDSD6 = 172334 MTC = 172522 TUC = 172440 SISA0 = 172240 SISA1 = 172242 SISD0 = 172200 SISD1 = 172202 IO = 177600 .data .globl _ka6 .globl _cputype _ka6: KDSA6 _cputype:45. stk: 0 .bss .globl nofault, ssr nofault:.=.+2 ssr: .=.+6 dispdly:.=.+2 saveps: .=.+2 140000 usize = 16. CSW = 177570 PS = 177776 SSR0 = 177572 SSR1 = 177574 SSR2 = 177576 SSR3 = 172516 KISA0 = 172340 KISA1 = 172342 KISA7 = 172356 KISD0 = 172300 KISD7 = 172316 KDSA0 = 172360 KDSA6 = 172374 KDSA7 = 172376 KDSD0 = 172320 KDSD5 = 172332 KDSD6 = 172334 MTC = 1725/ machine language assist / set up for 11-70 I and D space .fpp = 1 .mt = 0 /1 = tm11 0 = tju16 / non-UNIX instructions mfpi = 6500^tst mtpi = 6600^tst mfpd = 106500^tst mtpd = 106600^tst spl = 230 .if .fpp ldfps = 170100^tst stfps = 170200^tst .endif wait = 1 rtt = 6 reset = 5 HIPRI = 300 HIGH = 6 / Mag tape dump / save registers in low core and / write all core onto mag tape. / entry is thru 44 abs .data .globl dump dump: bit $1,SSR0 bne dump / save regs r0,r1,r2,r3,r4,r5,r6,KIA6 / starting at abs location 4 mov r0,4 mov $6,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ mov KDSA6,(r0)+ / dump all of core (ie to first mt error) / onto mag tape. (9 track or 7 track 'binary') .if .mt mov $MTC,r0 mov $60004,(r0)+ clr 2(r0) 1: mov $-512.,(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset / end of file and loop mov $60007,-(r0) br . .endif .if .mt-1 mov $TUC,r0 mov $60,(r0)+ clr 2(r0) clr 6(r0) mov $1300,24.(r0) / 800 bpi + pdp11 mode + unit zero 1: mov $-256.,(r0) mov $-512.,4(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset mov $027,-(r0) br . .endif .globl start, _end, _edata, _etext, _main / 11/45 and 11/70 startup. / entry is thru 0 abs. / since core is shuffled, / this code can be executed but once start: inc $-1 bne . reset / Set loc. 0 to trap to system, in case of / hardware glitch mov $trap,0 / in case of bad trap through 0 mov $340+15.,2 / high pri, trap type 15 clr PS / set KI0 to physical 0  mov $77406,r3 mov $KISA0,r0 mov $KISD0,r1 clr (r0)+ mov r3,(r1)+ / set KI1-6 to eventual text resting place mov $_end+63.,r2 ash $-6,r2 bic $!1777,r2 1: mov r2,(r0)+ mov r3,(r1)+ add $200,r2 cmp r0,$KISA7 blos 1b / set KI7 to IO seg for escape mov $IO,-(r0) / set KD0-7 to physical mov $KDSA0,r0 mov $KDSD0,r1 clr r2 1: mov r2,(r0)+ mov r3,(r1)+ add $200,r2 cmp r0,$KDSA7 blos 1b / initialization / get a temp (1-word) stack / turn on segmentation / copy text to I space / clear bss in D space mov $stk+2,sp mov $65,SSR3 / 22-bit, map, K+U sep i and d mov $3,*$MSCR / Disable UNIBUS traps, non-fatal traps inc SSR0 mov $_etext+100,r2 mov $_edata+100,r1 add $_etext-8192.,r1 1: mov -(r1),-(sp) mtpi -(r2) cmp r1,$_edata bhi 1b 1: clr (r1)+ cmp r1,$_end blo 1b / use KI escape to set KD7 to IO seg / set KD6 to first available core mov $IO,-(sp) mtpi *$KDSA7 mov $_etext-8192.+63.,r2 ash $-6,r2 bic $!1777,r2 add KISA1,r2 mov r2,KDSA6 mov $usize-1,$KDSD6+1 / Turn off write permission on kernel text / Take stuff above data out of address space mov $KISD0,r0 1: mov $77402,(r0)+ cmp r0,$KISD7 blo 1b mov $_end+63.,r0 ash $-6,r0 bic $!1777,r0 mov $KDSD0,r1 1: cmp r0,$200 bge 2f dec r0 bge 4f clr (r1) br 3f 4: movb r0,1(r1) br 3f 2: movb $177,1(r1) 3: tst (r1)+ sub $200,r0 cmp r1,$KDSD5 blos 1b / set up supervisor D registers mov $6,SISD0 mov $6,SISD1 / set up real sp / clear user block mov $_u+[usize*64.],sp mov $_u,r0 1: clr (r0)+ cmp r0,sp  blo 1b / set up previous mode and call main / on return, enter user mode at 0R mov $30000,PS jsr pc,_main mov $170000,-(sp) clr -(sp) rtt .globl trap, call .globl _trap / all traps and interrupts are / vectored thru this routine. trap: mov PS,saveps tst nofault bne 1f mov SSR0,ssr mov SSR1,ssr+2 mov SSR2,ssr+4 mov $1,SSR0 jsr r0,call1; _trap / no return 1: mov $1,SSR0 mov nofault,(sp) rtt .text .globl _runrun, _qswtch call1: mov saveps,-(sp) spl 0 br 1f call: mov PS,-(sp) 1: mov r1,-(sp) mfpd sp mov 4(sp),-(sp) bic $!37,(sp) bit $30000,PS beq 1f .if .fpp mov $20,_u+4 / FP maint mode .endif jsr pc,*(r0)+ 2: spl HIGH tstb _runrun beq 2f spl 0 jsr pc,_savfp jsr pc,_qswtch br 2b 2: .if .fpp mov $_u+4,r1 bit $20,(r1) bne 2f mov (r1)+,r0 ldfps r0 movf (r1)+,fr0 movf (r1)+,fr1 movf fr1,fr4 movf (r1)+,fr1 movf fr1,fr5 movf (r1)+,fr1 movf (r1)+,fr2 movf (r1)+,fr3 ldfps r0 2: .endif tst (sp)+ mtpd sp br 2f 1: bis $30000,PS jsr pc,*(r0)+ cmp (sp)+,(sp)+ 2: mov (sp)+,r1 tst (sp)+ mov (sp)+,r0 rtt .globl _savfp _savfp: .if .fpp mov $_u+4,r1 bit $20,(r1) beq 1f stfps (r1)+ movf fr0,(r1)+ movf fr4,fr0 movf fr0,(r1)+ movf fr5,fr0 movf fr0,(r1)+ movf fr1,(r1)+ movf fr2,(r1)+ movf fr3,(r1)+ 1: .endif rts pc .globl _incupc _incupc: mov r2,-(sp) mov 6(sp),r2 / base of prof with base,leng,off,scale mov 4(sp),r0 / pc sub 4(r2),r0 / offset clc ror r0 mul 6(r2),r0 / scale ashc $-14.,r0 inc r1 bic $1,r1 cmp r1,2(r2) / length bhis 1f add (r2),r1 / base mov nofault,-(sp) mov $2f,nofault mfpd (r1) inc (sp) mtpd (r1) br 3f 2: clr 6(r2) 3: mov (sp)+,nofault 1: mov (sp)+,r2 rts pc .globl _display _display: dec dispdly bge 2f clr dispdly mov PS,-(sp) mov $HIPRI,PS mov CSW,r1 bit $1,r1 beq 1f bis $30000,PS dec r1 1: jsr pc,fuword mov r0,CSW mov (sp)+,PS cmp r0,$-1 bne 2f mov $120.,dispdly / 2 sec delay after CSW fault 2: rts pc / Character list get/put .globl _getc, _putc .globl _cfreelist _getc: mov 2(sp),r1 mov PS,-(sp) mov r2,-(sp) spl 6 mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ / count bne 1f clr (r1)+ clr (r1)+ / last block br 2f 1: bit $7,r2 bne 3f mov -10(r2),(r1) / next block add $2,(r1) 2: dec r2 bic $7,r2 mov _cfreelist,(r2) mov r2,_cfreelist 3: mov (sp)+,r2 mov (sp)+,PS rts pc 9: clr 4(r1) mov $-1,r0 mov (sp)+,r2 mov (sp)+,PS rts pc _putc: mov 2(sp),r0 mov 4(sp),r1 mov PS,-(sp) mov r2,-(sp) mov r3,-(sp) spl 6 mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist clr (r2)+ mov r2,2(r1) / first ptr br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3 beq 9f mov (r3),_cfreelist mov r3,-10(r2) mov r3,r2 clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) / count clr r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc 9: mov pc,r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc .globl _backup .globl _regloc _backup: mov 2(sp),r0 movb ssr+2,r1 jsr pc,1f movb ssr+3,r1 jsr pc,1f movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 2: rts pc 1: mov r1,-(sp) asr (sp) asr (sp) asr (sp) bic $!7,r1 movb _regloc(r1),r1 asl r1 add r0,r1 sub (sp)+,(r1) rts pc .globl _fubyte, _subyte .globl _fuword, _suword .globl _fuibyte, _suibyte .globl _fuiword, _suiword _fuibyte: mov 2(sp),r1 bic $1,r1 jsr pc,giword br 2f _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword 2: cmp r1,2(sp) beq 1f swab r0 1: bic $!377,r0 rts pc _suibyte: mov 2(sp),r1 bic $1,r1 jsr pc,giword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,piword clr r0 rts pc _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,pword clr r0 rts pc _fuiword: mov 2(sp),r1 fuiword: jsr pc,giword rts pc _fuword: mov 2(sp),r1 fuword: jsr pc,gword rts pc giword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mfpi (r1) mov (sp)+,r0 br 1f gword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mfpd (r1) mov (sp)+,r0 br 1f _suiword: mov 2(sp),r1 mov 4(sp),r0 suiword: jsr pc,piword rts pc _suword: mov 2(sp),r1 mov 4(sp),r0 suword: jsr pc,pword rts pc piword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpi (r1) br 1f pword: mov PS,-(sp) spl HIGH mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpd (r1) 1: mov (sp)+,nofault mov (sp)+,PS rts pc err: mov (sp)+,nofault mov (sp)+,PS tst (sp)+ mov $-1,r0 rts pc .globl _copyin, _copyout .globl _copyiin, _copyiout _copyiin: jsr pc,copsu 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyin: jsr pc,copsu 1: mfpd (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyiout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpi (r1)+ sob r2,1b br 2f _copyout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpd (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 14(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc .globl _idle, _waitloc _idle: mov PS,-(sp) spl 0 wait _waitloc: mov (sp)+,PS rts pc .globl _savu, _retu, _aretu _savu: spl HIGH mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ spl 0 jmp (r1) _aretu: spl 7 mov (sp)+,r1 mov (sp),r0 br 1f _retu: spl 7 mov (sp)+,r1 mov (sp),KDSA6 mov $_u,r0 1: mov (r0)+,sp mov (r0)+,r5 spl 0 jmp (r1) .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: spl 0 rts pc _spl1: spl 1 rts pc _spl4: spl 4 rts pc _spl5: spl 5 rts pc _spl6: spl 6 rts pc _spl7: spl HIGH rts pc .globl _copyseg _copyseg: mov PS,-(sp) mov 4(sp),SISA0 mov 6(sp),SISA1 mov $10000+HIPRI,PS mov r2,-(sp) clr r0 mov $8192.,r1 mov $32.,r2 1: mfpd (r0)+ mtpd (r1)+ sob r2,1b mov (sp)+,r2 mov (sp)+,PS rts pc .globl _clearseg _clearseg: mov PS,-(sp) mov 4(sp),SISA0 mov $10000+HIPRI,PS clr r0 mov $32.,r1 1: clr -(sp)  mtpd (r0)+ sob r1,1b mov (sp)+,PS rts pc .globl _dpadd _dpadd: mov 2(sp),r0 add 4(sp),2(r0) adc (r0) rts pc .globl _dpcmp _dpcmp: mov 2(sp),r0 mov 4(sp),r1 sub 6(sp),r0 sub 8(sp),r1 sbc r0 bge 1f cmp r0,$-1 bne 2f cmp r1,$-512. bhi 3f 2: mov $-512.,r0 rts pc 1: bne 2f cmp r1,$512. blo 3f 2: mov $512.,r1 3: mov r1,r0 rts pc .globl _ldiv _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc .globl _lrem _lrem: clr r0 mov 2(sp),r1 div 4(sp),r0 mov r1,r0 rts pc .globl _lshift _lshift: mov 2(sp),r1 mov (r1)+,r0 mov (r1),r1 ashc 4(sp),r0 mov r1,r0 rts pc .globl csv csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) .globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc .globl _u _u = 140000 usize = 16. CSW = 177570 PS = 177776 SSR0 = 177572 SSR1 = 177574 SSR2 = 177576 SSR3 = 172516 KISA0 = 172340 KISA1 = 172342 KISA7 = 172356 KISD0 = 172300 KISD7 = 172316 KDSA0 = 172360 KDSA6 = 172374 KDSA7 = 172376 KDSD0 = 172320 KDSD5 = 172332 KDSD6 = 172334 MTC = 172522 TUC = 172440 SISA0 = 172240 SISA1 = 172242 SISD0 = 172200 SISD1 = 172202 MSCR = 017777746 / 11/70 memory control register IO = 177600 .data .globl _ka6 .globl _cputype _ka6: KDSA6 _cputype:70. stk: 0 .bss .globl nofault, ssr nofault:.=.+2 ssr: .=.+6 dispdly:.=.+2 saveps: .=.+2 0 = 177572 SSR1 = 177574 SSR2 = 177576 SSR3 = 172516 KISA0 = 172340 KISA1 = 172342 KISA7 = 172356 KISD0 = 172300 KISD7 = 172316 KDSA0 = 172360 KDSA6 = 172374 KDSA7 = 1# #include "../head/param.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/systm.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/text.h" #include "../head/textx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/seg.h" #define CLOCK1 0177546 #define CLOCK2 0172540 /* * Icode is the octal bootstrap * program executed in user mode * to bring up the system. */ int icode[] { 0104413, /* sys exec; init; initp */ 0000014, 0000010, 0000777, /* br . */ 0000014, /* initp: init; 0 */ 0000000, 0062457, /* init: */ 0061564, 0064457, 0064556, 0000164, }; /* * Initialization code. * Called from m40.s or m45.s as * soon as a stack and segmentation * have been established. * Functions: * clear and free user core * find which clock is configured * hand craft 0th process * call all initialization routines * fork - process 0 to schedule * - process 1 execute bootstrap * * panic: no clock -- neither clock responds * loop at loc 6 in user mode -- /etc/init * cannot be executed. */ main() { register i; /* * zero and free all of core */ printf("UNIX PG-1C300 Issue 3\n"); i = *ka6 + USIZE; UISD->r[0] = 077406; for(;maxmemr[0] = i; if(fuibyte(0) < 0) break; clearseg(i); maxmem++; mfree(coremap, 1, i); i++; } if(cputype == 70) for(i=0; i<62; i=+2) { UBMAP->r[i] = i<<12; UBMAP->r[i+1] = 0; } printf("mem = %l\n", maxmem*5/16); maxmem = min(maxmem, MAXMEM); mfree(ubmap, 23, 8); mfree(swapmap, nswap, swplo); /* * determine clock */ UISA->r[7] = ka6[1]; /* io segment */ UISD->r[7] = 077406; lks = CLOCK1; if(fuiword(lks) == -1) { lks = CLOCK2; if(fuiword(lks) == -1) panic("no clock"); } /* * set up system process */ proc[0].p_addr = *ka6; proc[0].p_size = USIZE; proc[0].p_stat = SRUN; proc[0].p_flag =| SLOAD|SSYS; u.u_procp = &proc[0]; /* * set up 'known' i-nodes */ *lks = 0115; cinit(); binit(); iinit(); msginit(); rootdir = iget(rootdev, ROOTINO); rootdir->i_flag =& ~ILOCK; u.u_cdir = iget(rootdev, ROOTINO); u.u_cdir->i_flag =& ~ILOCK; u.u_rdir = iget(rootdev, ROOTINO); u.u_rdir->i_flag =& ~ILOCK; /* * make init process * enter scheduling loop * with system process */ if(newproc()) { expand(USIZE+1); estabur(0, 1, 0, 0, RO); copyout(icode, 0, sizeof icode); /* * Return goes to loc. 0 of user init * code just copied out. */ return; } sched(); } /* * Load the user hardware segmentation * registers from the software prototype. * The software registers must have * been setup prior by estabur. */ sureg() { register *udp, *uap, *rdp; int *rap, daddr, taddr, *limudp; taddr = daddr = u.u_procp->p_addr; if (udp=u.u_procp->p_textp) taddr = udp->x_caddr; limudp = &u.u_uisd[16]; if (cputype==40) limudp = &u.u_uisd[8]; rap = UISA; rdp = UISD; uap = &u.u_uisa[0]; for (udp = &u.u_uisd[0]; udp < limudp;) { *rap++ = *uap++ + (*udp&TX? taddr: daddr); *rdp++ = *udp++; } } /*  * Set up software prototype segmentation * registers to implement the 3 pseudo * text,data,stack segment sizes passed * as arguments. * The argument sep specifies if the * text and data+stack segments are to * be separated. * The last argument determines whether the text * segment is read-write or read-only. */ estabur(nt, nd, ns, sep, xrw) { register a, *ap, *dp; if(checkur(nt, nd, ns, sep)) return(-1); a = 0; ap = &u.u_uisa[0]; dp = &u.u_uisd[0]; while(nt >= 128) { *dp++ = (127<<8) | xrw|TX; *ap++ = a; a =+ 128; nt =- 128; } if(nt) { *dp++ = ((nt-1)<<8) | xrw|TX; *ap++ = a; } if(sep) while(ap < &u.u_uisa[8]) { *ap++ = 0; *dp++ = 0; } a = USIZE; while(nd >= 128) { *dp++ = (127<<8) | RW; *ap++ = a; a =+ 128; nd =- 128; } if(nd) { *dp++ = ((nd-1)<<8) | RW; *ap++ = a; a =+ nd; } while(ap < &u.u_uisa[8]) { *dp++ = 0; *ap++ = 0; } if(sep) while(ap < &u.u_uisa[16]) { *dp++ = 0; *ap++ = 0; } a =+ ns; while(ns >= 128) { a =- 128; ns =- 128; *--dp = (127<<8) | RW; *--ap = a; } if(ns) { *--dp = ((128-ns)<<8) | RW | ED; *--ap = a-128; } if(!sep) { ap = &u.u_uisa[0]; dp = &u.u_uisa[8]; while(ap < &u.u_uisa[8]) *dp++ = *ap++; ap = &u.u_uisd[0]; dp = &u.u_uisd[8]; while(ap < &u.u_uisd[8]) *dp++ = *ap++; } sureg(); return(0); } checkur(nt, nd, ns, sep) { if(sep) { if(cputype == 40) goto err; if(ctos(nt) > 8 || ctos(nd)+ctos(ns) > 8) goto err; } else if(ctos(nt)+ctos(nd)+ctos(ns) > 8) goto err; if(nt+nd+ns+USIZE > maxmem) goto err; return(0); err: u.u_error = ENOMEM; return(-1); } *--ap = a-128; } if(!sep) { ap = &u.u_uisa[0]; dp = &u.u_uisa[8]; while(ap < &u.u_uisa[8]) *dp++ = *ap++; ap = &u.u_uisd[0]; dp = &u.u_uisd[8]; while(ap < &u.u_uisd[8]) *dp++ = *ap++; } sureg(); return(0); } checkur(nt, nd, ns, sep) { if(sep) { if(cputype == 40) goto err; if(ctos(nt) > 8 || ctos(nd)+ctos(ns) > 8) goto err; } else if(ctos(nt)+ctos(nd)+ctos(ns) > 8) goto err; if#include "../head/param.h" #include "../head/reg.h" #include "../head/ipcomm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" struct msgqhdr *logqp; /* for error logging */ struct msgqhdr msgqhdr[NMQHDR]; int msgmap[MMAPSIZ]; /* space for message allocation */ int msgcore[MSGMEM*16]; /* space for messages */ int movrhead, msgslept, mmemwant; /* * Message System Call */ messag() { register int n; register struct msgqhdr *rqp; register struct msghdr *hp; int mtest;  mtest = 0; switch(u.u_arg[0]) { default: u.u_error = EINVAL; return; case MDISAB: msgflush(); return; case MENAB: if(u.u_msgqhdr != NULL) return; for(rqp = &msgqhdr[0];rqp < &msgqhdr[NMQHDR];rqp++) if(rqp->mq_procp == NULL) { rqp->mq_forw = NULL; rqp->mq_last = &rqp->mq_forw; rqp->mq_cnt = 0; rqp->mq_flag = 0; u.u_msgqhdr = rqp; rqp->mq_procp = u.u_procp; return; } u.u_error = ETABLE; return; case MSEND: mtest++; case MSENDW:  if((n = u.u_ar0[R0]) < 0 || n > MAXMLEN || u.u_arg[3] <= 0 || u.u_arg[3] > 128) { u.u_error = EINVAL; return; } if((rqp = mqsrch(u.u_arg[2])) == NULL) { u.u_error = ESRCH; return; } if(rqp->mq_cnt >= MAXMSG) { u.u_error = ETABLE; return; } while((hp = msgsetup(n)) == NULL) { if(mtest) { u.u_error = ENOMEM; return; } mmemwant++; msgslept++; sleep(msgcore, PMSG); if(rqp->mq_procp == NULL || rqp->mq_procp->p_pid != u.u_arg[2]) { u.u_error = ESRCH; return; } } msgmove(hp, n, MSGIN); if(u.u_error) msgfree(hp); else { hp->mq_type = u.u_arg[3]; hp->mq_sender = u.u_procp->p_pid; msgsend(rqp, hp); } return; case MRECV: mtest++; case MRECVW: if((rqp = u.u_msgqhdr) == NULL) { u.u_error = ENOALOC; return; } if((n = u.u_arg[3]) < 0 || n > 128 || u.u_ar0[R0] < 0) { u.u_error = EINVAL; return; } while(!msgrecv(rqp, n)) { if(mtest) { u.u_error = ENOMSG; return; } rqp->mq_flag =| IP_WANTED; sleep(rqp, PMSG); } return; } } /* * Scan a process's message Q for a message of * the desired type. If found, try to effect transfer * of the message to the process. */ msgrecv(qp, type) struct msgqhdr *qp; { register int n; register struct msghdr *rhp1, *rhp2; n = type; for(rhp1 = qp; rhp2 = rhp1->mq_forw; rhp1 = rhp2) if(n == 0 || n == rhp2->mq_type) { n = min(rhp2->mq_size, u.u_ar0[R0]); msgmove(rhp2, n, MSGOUT); if(u.u_error) return(1); if(suword(u.u_arg[2], rhp2->mq_sender) == -1 || suword(u.u_arg[2]+2, rhp2->mq_type) == -1) u.u_error = EFAULT; else { msgremov(qp, rhp1); msgfree(rhp2); u.u_ar0[R0] = n; } return(1); } return(0); } /* * Place the message pointed to by "hp" on the message Q * pointed to by "qp". Awaken the process if it's waiting * for arrival of a message. */ msgsend(qp, hp) struct msgqhdr *qp; struct msghdr *hp; { register int s; register struct msgqhdr *rqp; rqp = qp; hp->mq_forw = NULL; s = PS->integ; spl6(); rqp->mq_last->mq_forw = hp; rqp->mq_last = hp; rqp->mq_cnt++; PS->integ = s; if(rqp->mq_flag & IP_WANTED) { rqp->mq_flag =& ~IP_WANTED; wakeup(rqp); } } /* * Alloc buffer space for a message and its * associated header. The spl6 is needed only * when messages are used for system error logging. */ msgsetup(size) { register int s; register struct msghdr *rhp; s = PS->integ; spl6(); if((rhp = malloc(msgmap, (size+movrhead)&(~31))) != NULL) rhp->mq_size = size; PS->integ = s; return(rhp); } /* * Deallocate a message Q header and any messages * pending on the Q. Messages requiring an ACK * (types 1-63) are returned to the sending process as * type 128, if possible. */ msgflush() { register struct msgqhdr *rqp1, *rqp2; register struct msghdr *rhp; if((rqp1 = u.u_msgqhdr) == NULL) { u.u_error = ENOALOC; return; } if(rqp1 == logqp) /* implicit termination of error log */ termlog(); u.u_msgqhdr = NULL; rqp1->mq_procp = NULL; while((rhp = rqp1->mq_forw) != NULL) { msgremov(rqp1, rqp1); if((rhp->mq_type) < 64 && (rqp2 = mqsrch(rhp->mq_sender)) && rqp2->mq_cnt < MAXMSG) { rhp->mq_type = 128; msgsend(rqp2, rhp); } else msgfree(rhp); } } /* * Remove a message from a message Q. */ msgremov(qp, prevhp) struct msgqhdr *qp; struct msghdr *prevhp; { register int s; register struct msghdr *rhp1, *rhp2; rhp1 = prevhp; rhp2 = rhp1->mq_forw; s = PS->integ; spl6(); qp->mq_cnt--; if((rhp1->mq_forw = rhp2->mq_forw) == NULL) qp->mq_last = rhp1; PS->integ = s; } /* * Free the buffer space used by a message and its header. * Awaken any processes roadblocked because of * insufficient buffer space. */ msgfree(hp) struct msghdr *hp; { register int s; s = PS->integ; spl6(); mfree(msgmap, (hp->mq_size+movrhead)&(~31), hp); PS->integ = s; if(mmemwant) { mmemwant = 0; wakeup(msgcore); } } /* * Message interface to iomove() */ msgmove(hp, count, mode) struct msghdr *hp; { register int len; if((len = count) == 0) return; u.u_offset[0] = 0; u.u_offset[1] = 0; u.u_count = len; u.u_base = u.u_arg[1]; u.u_segflg = 0; iomove(++hp, 0, len, mode | MSGIO); } /* * See if a process is enabled for messages */ mqsrch(pid) { register struct proc *rpp; register struct msgqhdr *rqp; register id; id = pid; for(rqp = &msgqhdr[0]; rqp < &msgqhdr[NMQHDR]; rqp++) if((rpp = rqp->mq_procp) != NULL && rpp->p_pid == id) return(rqp); return(NULL); } /* * Initialization */ msginit() { struct msghdr proto; movrhead = sizeof(proto) + 31; mfree(msgmap, sizeof(msgcore), msgcore); } ; u.u_base = u.u_arg[1]; u.u_segflg = 0; iomove(++hp, 0, len, mode | MSGIO); } /* * See if a process is enabled for messages */ mqsrch(pid) { register struct proc *rpp; register struct msgqhdr *rqp; register id; id = pid; for(rqp = &msgqhdr[0]; rqp < &msgqhdr[NMQHDR]; rqp++) if((rpp = rqp->mq_procp) != NULL && rpp->p_pid == id) return(rqp); return(NULL); } /* * Initialization */ msginit() { struct #include "../head/param.h" /* * Fake Message System Call */ messag() { nosys(); } msgrecv() { } msgsend() { } msgsetup() { return(NULL); } msgflush() { } msgremov() { } msgfree() { } msgmove() { } mqsrch() { return(NULL); } msginit() { } proc *rpp; register struct msgqhdr *rqp; register id; id = pid; for(rqp = &msgqhdr[0]; rqp < &msgqhdr[NMQHDR]; rqp++) if((rpp = rqp->mq_procp) != NULL && rpp->p_pid == id) return(rqp); return(NULL); } /* * Initialization */ msginit() { struct # #include "../head/param.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/systm.h" #include "../head/buf.h" #include "../head/bufx.h" /* * Convert a pathname into a pointer to * an inode. Note that the inode is locked. * * func = function called to get next char of name * &uchar if name is in user space * &schar if name is in system space * flag = 0 if name is sought * 1 if name is to be created * 2 if name is to be deleted */ namei(func, flag) int (*func)(); { register struct inode *dp; register c; register char *cp; int eo, *bp; /* * If name starts with '/' start from * root; otherwise start from current dir. */ dp = u.u_cdir; if((c=(*func)()) == '/') dp = u.u_rdir; iget(dp->i_dev, dp->i_number); while(c == '/') c = (*func)(); if(c == '\0' && flag != 0) { u.u_error = ENOENT; goto out; } cloop: /* * Here dp contains pointer * to last component matched. */ if(u.u_error) goto out;  if(c == '\0') return(dp); /* * If there is another component, * dp must be a directory and * must have x permission. */ if((dp->i_mode&IFMT) != IFDIR || dp->i_nlink==0) { u.u_error = ENOTDIR; goto out; } if(access(dp, IEXEC)) goto out; /* * Gather up name into * users' dir buffer. */ cp = &u.u_dbuf[0]; while(c!='/' && c!='\0' && u.u_error==0) { if(cp < &u.u_dbuf[DIRSIZ]) *cp++ = c; c = (*func)(); } while(cp < &u.u_dbuf[DIRSIZ]) *cp++ = '\0'; while(c == '/') c = (*func)(); if(u.u_error) goto out; /* * Set up to search a directory. */ u.u_offset[1] = 0; u.u_offset[0] = 0; u.u_segflg = 1; eo = 0; u.u_count = ldiv(dp->i_size1, DIRSIZ+2); bp = NULL; eloop: /* * If at the end of the directory, * the search failed. Report what * is appropriate as per flag. */ if(u.u_count == 0) { if(bp != NULL) brelse(bp); if(flag==1 && c=='\0') { if(access(dp, IWRITE)) goto out; u.u_pdir = dp; if(eo) u.u_offset[1] = eo-DIRSIZ-2; else dp->i_flag =| IUPD; return(NULL); } u.u_error = ENOENT; goto out; } /* * If offset is on a block boundary, * read the next directory block. * Release previous if it exists. */ if((u.u_offset[1]&0777) == 0) { if(bp != NULL) brelse(bp); bp = bread(dp->i_dev, bmap(dp, ldiv(u.u_offset[1], 512))); } /* * Note first empty directory slot * in eo for possible creat. * String compare the directory entry * and the current component. * If they do not match, go back to eloop. */ bcopy(bp->b_addr+(u.u_offset[1]&0777), &u.u_dent, (DIRSIZ+2)/2); u.u_offset[1] =+ DIRSIZ+2; u.u_count--; if(u.u_dent.u_ino == 0) { if(eo == 0) eo = u.u_offset[1]; goto eloop; } for(cp = &u.u_dbuf[0]; cp < &u.u_dbuf[DIRSIZ]; cp++) if(*cp != cp[u.u_dent.u_name - u.u_dbuf]) goto eloop; /* * Here a component matched in a directory. * If there is more pathname, go back to * cloop, otherwise return. */ if(bp != NULL) brelse(bp); if(flag==2 && c=='\0') { if(access(dp, IWRITE)) goto out; return(dp); } bp = dp->i_dev; iput(dp); dp = iget(bp, u.u_dent.u_ino); if(dp == NULL) return(NULL); goto cloop; out: iput(dp); return(NULL); } /* * Return the next character from the * kernel string pointed at by dirp. */ schar() { return(*u.u_dirp++ & 0377); } /* * Return the next character from the * user string pointed at by dirp. */ uchar() { register c; c = fubyte(u.u_dirp++); if(c == -1) u.u_error = EFAULT; return(c); } && c=='\0') { if(access(d# #include "../head/param.h" #include "../head/seg.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/systm.h" /* * Address and structure of the * KL-11 console device registers. */ struct { int rsr; int rbr; int xsr; int xbr; }; char *msgbufp msgbuf; /* Next saved printf character */ /* * In case console is off, * panicstr contains argument to last * call to panic. */ char *panicstr; /* * Scaled down version of C Library printf. * Only %s %l %d (==%l) %o are recognized. * Used to print diagnostic information * directly on console tty. * Since it is not interrupt driven, * all system activities are pretty much * suspended. * Printf should not be used for chit-chat. */ printf(fmt,x1) char fmt[]; { register char *s; register *adx, c; adx = &x1; loop: while((c = *fmt++) != '%') { if(c == '\0') return; putchar(c); } c = *fmt++; if((c == 'd')&&(*adx < 0)){ *adx = -*adx; putchar('-'); } if(c == 'd' || c == 'l' || c == 'o')  printn(*adx, c=='o'? 8: 10); if(c == 's') { s = *adx; while(c = *s++) putchar(c); }else if(c == 'c') putchar(*adx); adx++; goto loop; } /* * Print an unsigned integer in base b. */ printn(n, b) { register a; if(a = ldiv(n, b)) printn(a, b); putchar(lrem(n, b) + '0'); } /* * Print a character on console. * Attempts to save and restore device * status. * If the switches are 0, all * printing is inhibited. * * Whether or not printing is inhibited, * the last MSGBUFS characters  * are saved in msgbuf for inspection later. */ putchar(c) { register rc, s, timo; rc = c; if (rc!='\0' && rc!='\r' && rc!=0177) { *msgbufp++ = rc; if (msgbufp >= &msgbuf[MSGBUFS]) msgbufp = msgbuf; } if(SW->integ == 0) return; timo = 30000; /* * Try waiting for the console tty to come ready, * otherwise give up after a reasonable time. */ while((KL->xsr&0200)==0 && --timo!=0) ; if(rc == 0) return; s = KL->xsr; KL->xsr = 0; KL->xbr = rc; if(rc == '\n') { putchar('\r'); putchar(0177); putchar(0177); } putchar(0); KL->xsr = s; } /* * Panic is called on unresolvable * fatal errors. * It syncs, prints "panic: mesg" and * then loops. */ panic(s) char *s; { panicstr = s; update(); printf("panic: %s\n", s); for(;;) idle(); } /* * prdev prints a warning message of the * form "mesg on dev x/y". * x and y are the major and minor parts of * the device argument. */ prdev(str, dev) { printf("%s on dev %l/%l\n", str, dev.d_major, dev.d_minor); } /* * deverr prints a diagnostic from * a device driver. * It prints the device, block number, * and an octal word (usually some error * status register) passed as argument. */ /* Unused deverror(bp, o1, o2) int *bp; { register *rbp; rbp = bp; prdev("err", rbp->b_dev); printf("bn%l er%o %o\n", rbp->b_blkno, o1, o2); } */ form "mesg on dev x/y". * x and y are the major and minor parts of * the device argument. */ prdev(str, dev) { printf("%s on dev %l/%l\n", str, dev.d_major, dev.d_minor); } /* * deverr p# #include "../head/param.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/conf.h" #include "../head/systm.h" #include "../head/ipcomm.h" /* * Read the file corresponding to * the inode pointed at by the argument. * The actual read arguments are found * in the variables: * u_base core address for destination * u_offset byte offset in file * u_count number of bytes to read * u_segflg read to kernel/user/user I */ readi(aip) struct inode *aip; { int *bp; int lbn, bn, on; register dn, n; register struct inode *ip; ip = aip; if(u.u_count == 0) return; ip->i_flag =| IACC; if((ip->i_mode&IFMT) == IFCHR) { (*cdevsw[ip->i_addr[0].d_major].d_read)(ip->i_addr[0]); return; } do { lbn = bn = lshift(u.u_offset, -9); on = u.u_offset[1] & 0777; n = min(512-on, u.u_count); if((ip->i_mode&IFMT) != IFBLK) { dn = dpcmp(ip->i_size0&0377, ip->i_size1, u.u_offset[0], u.u_offset[1]); if(dn <= 0) return; n = min(n, dn); if ((bn = bmap(ip, lbn)) == 0) return; dn = ip->i_dev; } else { dn = ip->i_addr[0]; rablock = bn+1; } if (ip->i_lastr+1 == lbn) bp = breada(dn, bn, rablock); else bp = bread(dn, bn); ip->i_lastr = lbn; dn = ((bp->b_resid-bp->b_wcount)<<1) - on; if (ni_flag =| IACC|IUPD; if((ip->i_mode&IFMT) == IFCHR) { (*cdevsw[ip->i_addr[0].d_major].d_write)(ip->i_addr[0]); return; } if (u.u_count == 0) return; do { bn = lshift(u.u_offset, -9); on = u.u_offset[1] & 0777; n = min(512-on, u.u_count); if((ip->i_mode&IFMT) != IFBLK) { if ((bn = bmap(ip, bn)) == 0) return; dn = ip->i_dev; } else dn = ip->i_addr[0]; if(n == 512) bp = getblk(dn, bn); else bp = bread(dn, bn); iomove(bp, on, n, B_WRITE); if(u.u_error != 0) brelse(bp); else if ((u.u_offset[1]&0777)==0) bawrite(bp); else bdwrite(bp); if(dpcmp(ip->i_size0&0377, ip->i_size1, u.u_offset[0], u.u_offset[1]) < 0 && (ip->i_mode&(IFBLK&IFCHR)) == 0) { ip->i_size0 = u.u_offset[0]; ip->i_size1 = u.u_offset[1]; } ip->i_flag =| IUPD; } while(u.u_error==0 && u.u_count!=0); } /* * Return the logical maximum * of the 2 arguments. */ max(a, b) char *a, *b; { if(a > b) return(a); return(b); } /* * Return the logical minimum * of the 2 arguments. */ min(a, b) char *a, *b; { if(a < b) return(a); return(b); } /* * Move 'an' bytes at byte location * &bp->b_addr[o] to/from (flag) the * user/kernel (u.segflg) area starting at u.base. * Update all the arguments by the number * of bytes moved. * * There are 2 algorithms, * if source address, dest address and count * are all even in a user copy, * then the machine language copyin/copyout * is called. * If not, its done byte-by-byte with * cpass and passc. */ iomove(bp, o, an, flag) int *bp; { register char *cp; register int n, t; n = an; if(u.u_error || n == 0) return; if(flag & MSGIO) { cp = bp; flag =& ~MSGIO; } else cp = bp->b_addr; cp =+ o; if(u.u_segflg!=1 && ((n | cp | u.u_base)&01)==0) { if (flag==B_WRITE) if (u.u_segflg==0) cp = copyin(u.u_base, cp, n); else cp = copyiin(u.u_base, cp, n); else if (u.u_segflg==0) cp = copyout(cp, u.u_base, n); else cp = copyiout(cp, u.u_base, n); if (cp) { u.u_error = EFAULT; return; } u.u_base =+ n; dpadd(u.u_offset, n); u.u_count =- n; return; } if (flag==B_WRITE) { while(n--) { if ((t = cpass()) < 0) return; *cp++ = t; } } else while (n--) if(passc(*cp++) < 0) return; } 1)==0) { if (flag==B_WRITE) if (u.u_segflg==0) cp = copyin(u.u_base, cp, n); else cp = copyiin(u.u_base, cp, n); else if (u.u_segflg==0) cp = copyout(cp, u.u_base, n); else cp = copyiout(cp, u.u_base, n); if (cp) { u.u_error = EFAULT; return; } u.u_base =+ n; dpadd(u.u_offset, n); u.u_count =- n; return; } if (flag==B_WRITE) { while(n--) { if ((t# #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/reg.h" #include "../head/text.h" #include "../head/textx.h" #include "../head/seg.h" /* * Priority for tracing */ #define IPCPRI 0 /* * Structure to access an array of integers. */ struct { int inta[]; }; /* * Tracing variables. * Used to pass trace command from * parent to child being traced. * This data base cannot be * shared and is locked * per user. */ struct { int ip_lock; int ip_req; int ip_addr; int ip_data; } ipc; /* * Send the specified signal to * all processes with 'pgrp' as * process group. * Called by tty.c for quits and * interrupts. */ signal(apgrp, sig) { register struct proc *p; register pgrp; if ((pgrp = apgrp)==0) return; for(p = &proc[0]; p < &proc[NPROC]; p++) if(p->p_pgrp == pgrp) psignal(p, sig); } /* * Send the specified signal to * the specified process. */ psignal(p, sig) int *p; { register *rp, a; a = sig; if(a >= NSIG) return; rp = p; if(a) rp->p_sig =| 1L<<(a-1); if(rp->p_pri > PUSER) rp->p_pri = PUSER; if(rp->p_stat == SSLEEP && rp->p_pri > 0) setrun(rp); } /* * Returns true if the current * process has a signal to process. * This is asked at least once * each time a process enters the * system. * A signal does not do anything * directly to a process; it sets * a flag that asks the process to * do something to itself. */ issig() { int n; register struct proc *p, *q; p = u.u_procp; while(p->p_sig) { n = fsig(p); if(n == SIGCLD) { if(u.u_signal[SIGCLD]&01) { for(q = &proc[0];q < &proc[NPROC];q++) if(p->p_pid==q->p_ppid && q->p_stat==SZOMB) freeproc(q, 0); } else if(u.u_signal[SIGCLD]) return(n); } else if((u.u_signal[n]&1) == 0 || (p->p_flag&STRC)) return(n); p->p_sig =& ~(1L<<(n-1)); } return(0); } /* * Enter the tracing STOP state. * In this state, the parent is * informed and the process is able to * receive commands from the parent. */ stop() { register struct proc *pp, *cp; loop: cp = u.u_procp; if(cp->p_ppid != 1) for (pp = &proc[0]; pp < &proc[NPROC]; pp++) if (pp->p_pid == cp->p_ppid) { wakeup(pp); cp->p_stat = SSTOP; swtch(); if ((cp->p_flag&STRC)==0 || procxmt()) return; goto loop; } exit(); } /* * Perform the action specified by * the current signal. * The usual sequence is: * if(issig()) * psig(); */ psig() { register n; int p; register *rp; rp = u.u_procp; if (rp->p_flag&STRC) stop(); n = fsig(rp); if (n==0) return; rp->p_sig =& ~(1L<<(n-1)); if((p=u.u_signal[n]) != 0) { u.u_error = 0; if(n != SIGINS && n != SIGTRC) u.u_signal[n] = 0; n = u.u_ar0[R6] - 4; grow(n); suword(n+2, u.u_ar0[RPS]); suword(n, u.u_ar0[R7]); u.u_ar0[R6] = n; u.u_ar0[RPS] =& ~TBIT; u.u_ar0[R7] = p; return; } switch(n) { case SIGQIT: case SIGINS: case SIGTRC: case SIGIOT: case SIGEMT: case SIGFPT: case SIGBUS: case SIGSEG: case SIGSYS: u.u_arg[0] = n; if(core()) n =+ 0200; } u.u_arg[0] = (u.u_ar0[R0]<<8) | n; exit(); } /* * find the signal in bit-position * representation in p_sig. */ fsig(p) struct proc *p; { register i; long n; register char *cp; n = p->p_sig; for(i=1; i> 1; } return(0); } /* * Create a core image on the file "core" * If you are looking for protection glitches, * there are probably a wealth of them here * when this occurs to a suid command. * * It writes USIZE block of the * user.h area followed by the entire * data+stack segments. */ core() { register s, *ip; extern schar; u.u_error = 0; u.u_dirp = "core"; ip = namei(&schar, 1); if(ip == NULL) { if(u.u_error) return(0); ip = maknode(0666); if (ip==NULL) return(0); } if(!access(ip, IWRITE) && (ip->i_mode&IFMT) == 0 && u.u_uid == u.u_ruid) { itrunc(ip); u.u_offset[0] = 0; u.u_offset[1] = 0; u.u_base = &u; u.u_count = USIZE*64; u.u_segflg = 1; writei(ip); s = u.u_procp->p_size - USIZE; estabur(0, s, 0, 0, RO); u.u_base = 0; u.u_count = s*64; u.u_segflg = 0; writei(ip); } iput(ip); return(u.u_error==0); } /* * grow the stack to include the SP * true return if successful. */ grow(sp) char *sp; { register a, si, i; if(sp >= -u.u_ssize*64) return(0); si = ldiv(-sp, 64) - u.u_ssize + SINCR; if(si <= 0) return(0); if(estabur(u.u_tsize, u.u_dsize, u.u_ssize+si, u.u_sep, RO)) return(0); expand(u.u_procp->p_size+si); a = u.u_procp->p_addr + u.u_procp->p_size; for(i=u.u_ssize; i; i--) { a--; copyseg(a-si, a); } for(i=si; i; i--) clearseg(--a); u.u_ssize =+ si; return(1); } /* * sys-trace system call. */ ptrace() { register struct proc *p; register struct text *xp; if (u.u_arg[2] <= 0) { u.u_procp->p_flag =| STRC; return; } for (p=proc; p < &proc[NPROC]; p++) if (p->p_stat==SSTOP && p->p_pid==u.u_arg[0] && p->p_ppid==u.u_procp->p_pid)  goto found; u.u_error = ESRCH; return; found: while (ipc.ip_lock) sleep(&ipc, IPCPRI); ipc.ip_lock = p->p_pid; ipc.ip_data = u.u_ar0[R0]; ipc.ip_addr = u.u_arg[1] & ~01; ipc.ip_req = u.u_arg[2]; p->p_flag =& ~SWTED; setrun(p); while (ipc.ip_req > 0) sleep(&ipc, IPCPRI); u.u_ar0[R0] = ipc.ip_data; if (ipc.ip_req < 0) u.u_error = EIO; ipc.ip_lock = 0; wakeup(&ipc); } /* * Code that the child process * executes to implement the command * of the parent process in tracing. */ procxmt() { register int i; register int *p; register struct text *xp; if (ipc.ip_lock != u.u_procp->p_pid) return(0); i = ipc.ip_req; ipc.ip_req = 0; wakeup(&ipc); switch (i) { /* read user I */ case 1: if (fuibyte(ipc.ip_addr) == -1) goto error; ipc.ip_data = fuiword(ipc.ip_addr); break; /* read user D */ case 2: if (fubyte(ipc.ip_addr) == -1) goto error; ipc.ip_data = fuword(ipc.ip_addr); break; /* read u */ case 3: i = ipc.ip_addr; if (i<0 || i >= (USIZE<<6)) goto error; ipc.ip_data = u.inta[i>>1]; break; /* write user I */ /* Must set up to allow writing */ case 4: /* * If text, must assure exclusive use */ if (xp = u.u_procp->p_textp) { if (xp->x_count!=1 || xp->x_iptr->i_mode&ISVTX) goto error; xp->x_iptr->i_flag =& ~ITEXT; } estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RW); i = suiword(ipc.ip_addr, 0); suiword(ipc.ip_addr, ipc.ip_data); estabur(u.u_tsize, u.u_dsize, u.u_ssize, u.u_sep, RO); if (i<0) goto error; if (xp) xp->x_flag =| XWRIT; break; /* write user D */ case 5: if (suword(ipc.ip_addr, 0) < 0) goto error; suword(ipc.ip_addr, ipc.ip_data); break; /* write u */ case 6: p = &u.inta[ipc.ip_addr>>1]; if (p >= u.u_fsav && p < &u.u_fsav[25]) goto ok; for (i=0; i<9; i++) if (p == &u.u_ar0[regloc[i]]) goto ok; goto error; ok: if (p == &u.u_ar0[RPS]) { ipc.ip_data =| 0170000; /* assure user space */ ipc.ip_data =& ~0340; /* priority 0 */ } *p = ipc.ip_data; break; /* set signal and continue */ case 7: u.u_procp->p_sig = 0; psignal(u.u_procp, ipc.ip_data); return(1); /* force exit */ case 8: exit(); default: error: ipc.ip_req = -1; } return(0); } _addr>>1]; if (p >= u.u_fsav && p < &u.u_fsav[25]) goto ok; for (i=0; i<9; i++) if (p == &u.u_ar0[regloc[i]]) goto ok; goto error; ok: if (p == &u.u_ar0[RPS]) { ipc.ip_data =| 0170000; /* assure user space */ ipc.ip_data =& ~0340; /* priority 0 */ } *p = ipc.ip_data; bre# #include "../head/param.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/text.h" #include "../head/textx.h" #include "../head/systm.h" #include "../head/file.h" #include "../head/filex.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/ipcomm.h" struct proc *procend {&proc[1]}; /* * Give up the processor till a wakeup occurs * on chan, at which time the process * enters the scheduling queue at priority pri. * The most important effect of pri is that when * pri<=0 a signal cannot disturb the sleep; * if pri>0 signals will be processed. * Callers of this routine must be prepared for * premature return, and check that the reason for * sleeping has gone away. */ sleep(chan, pri) { register *rp, s; s = PS->integ; rp = u.u_procp; spl6(); rp->p_stat = SSLEEP; rp->p_wchan = chan; rp->p_pri = pri; if(pri > 0) { if(issig()) { rp->p_wchan = 0; rp->p_stat = SRUN; spl0(); goto psig; } spl0(); if(runin != 0) { runin = 0; wakeup(&runin); } swtch(); if(issig()) goto psig; } else { spl0(); swtch(); } PS->integ = s; return; /* * If priority was low (>0) and * there has been a signal, * execute non-local goto to * the qsav location. * (see trap1/trap.c) */ psig: aretu(u.u_qsav); } /* * Wake up all processes sleeping on chan. */ wakeup(chan) { register struct proc *p; register c, i; c = chan; p = &proc[0]; i = procend - p; do { if(p->p_wchan==c && p->p_stat!=SZOMB) setrun(p); p++; } while(--i); } setrq(p) struct proc *p; { register struct proc *q; register s; s = PS->integ; spl6(); for(q=runq; q!=NULL; q=q->p_link) if(q == p) { printf("proc on q\n"); goto out; } p->p_link = runq; runq = p; out: PS->integ = s; } /* * Set the process running; * arrange for it to be swapped in if necessary. */ setrun(p) { register struct proc *rp; rp = p; if (rp->p_stat==0 || rp->p_stat==SZOMB) panic("Running a dead proc"); rp->p_wchan = 0; rp->p_stat = SRUN; setrq(p); if(rp->p_pri < curpri) runrun++; if(runout != 0 && (rp->p_flag&SLOAD) == 0) { runout = 0; wakeup(&runout); } } /* * Set user priority. * The rescheduling flag (runrun) * is set if the priority is better * than the currently running process. */ setpri(up) { register *pp, p; pp = up; p = (pp->p_cpu & 0377)/16; p =+ PUSER + pp->p_nice; if(p > 127) p = 127; if(p < curpri) runrun++; pp->p_pri = p; return(p); } /* * The main loop of the scheduling (swapping) * process. * The basic idea is: * see if anyone wants to be swapped in; * swap out processes until there is room; * swap him in; * repeat. * The runout flag is set whenever someone is swapped out. * Sched sleeps on it awaiting work. * * Sched sleeps on runin whenever it cannot find enough * core (by swapping out or otherwise) to fit the * selected swapped process. It is awakend when the * core situation changes and in any event once per second. */ sched() { register struct proc *rp, *p; register outage, inage; int maxsize; /* * find user to swap in; * of users ready, select one out longest */ loop: spl6(); outage = -20000; for (rp = &proc[0]; rp < procend; rp++) if (rp->p_stat==SRUN && (rp->p_flag&SLOAD)==0 && rp->p_time-rp->p_nice*8 > outage) { p = rp; outage = rp->p_time-rp->p_nice*8; } /* * If there is no one there, wait. */ if (outage == -20000) { runout++; sleep(&runout, PSWP); goto loop; } spl0(); /* * See if there is core for that process; * if so, swap it in. */ if (swapin(p)) goto loop; /* * none found. * look around for core. * Select the largest of those sleeping * at bad priority; if none, select the oldest. */ spl6(); p = NULL; maxsize = -1; inage = -1; for (rp = &proc[0]; rp < procend; rp++) { if ((rp->p_flag&(SSYS|SLOCK|SLOAD))!=SLOAD) continue; if (rp->p_textp && rp->p_textp->x_flag&XLOCK) continue; if (rp->p_stat==SSLEEP&&rp->p_pri>=0 || rp->p_stat==SSTOP) { if (maxsize < rp->p_size) { p = rp; maxsize = rp->p_size; } } else if (maxsize<0 && (rp->p_stat==SRUN||rp->p_stat==SSLEEP)) { if (rp->p_time+rp->p_nice > inage) { p = rp; inage = rp->p_time+rp->p_nice; } } } spl0(); /* * Swap found user out if sleeping at bad pri, * or if he has spent at least 2 seconds in core and * the swapped-out process has spent at least 3 seconds out. * Otherwise wait a bit and try again. */ if (maxsize>=0 || (outage>=3 && inage>=2)) { p->p_flag =& ~SLOAD; xswap(p, 1, 0); goto loop; } spl6(); runin++; sleep(&runin, PSWP); goto loop; } /* * Swap a process in. * Allocate data and possible text separately. * It would be better to do largest first. */ swapin(pp) struct proc *pp; { register struct proc *p; register struct text *xp; register int a; int x; p = pp; if ((a = malloc(coremap, p->p_size)) == NULL) return(0); if (xp = p->p_textp) { xlock(xp); if (xp->x_ccount==0) { if ((x = malloc(coremap, xp->x_size)) == NULL) { xunlock(xp); mfree(coremap, p->p_size, a); return(0); } xp->x_caddr = x; if ((xp->x_flag&XLOAD)==0) swap(xp->x_daddr,x,xp->x_size,B_READ); } xp->x_ccount++; xunlock(xp); } swap(p->p_addr, a, p->p_size, B_READ); mfree(swapmap, ctob(p->p_size), p->p_addr); p->p_addr = a; p->p_flag =| SLOAD; p->p_time = 0; return(1); } qswtch() { setrq(u.u_procp); swtch(); } /* * This routine is called to reschedule the CPU. * if the calling process is not in RUN state, * arrangements for it to restart must have * been made elsewhere, usually by calling via sleep. */ swtch() { register n; register struct proc *p, *q; static struct proc *pp, *pq; /* * Remember stack of caller * and switch to schedulers stack. */ savu(u.u_rsav); retu(proc[0].p_addr); loop: spl6(); runrun = 0; pp = NULL; q = NULL; n = 128; /* * Search for highest-priority runnable process */ for(p=runq; p!=NULL; p=p->p_link) { if((p->p_stat==SRUN) && (p->p_flag&SLOAD)) { if(p->p_pri < n) { pp = p; pq = q; n = p->p_pri; } } q = p; } /* * If no process is runnable, idle. */ p = pp; if(p == NULL) { idle(); spl0(); goto loop; } q = pq; if(q == NULL) runq = p->p_link; else q->p_link = p->p_link; curpri = n; spl0(); /* * Switch to stack of the new process and set up * his segmentation registers. */ retu(p->p_addr); sureg(); /* * If the new process paused because it was * swapped out, set the stack level to the last call * to savu(u_ssav). This means that the return * which is executed immediately after the call to aretu * actually returns from the last routine which did * the savu. */ if(p->p_flag&SSWAP) { p->p_flag =& ~SSWAP; aretu(u.u_ssav); } /* * The value returned here has many subtle implications. * See the newproc comments. */ return(1); } /* * Create a new process-- the internal version of * sys fork. * It returns 1 in the new process. * How this happens is rather hard to understand. * The essential fact is that the new process is created * in such a way that appears to have started executing * in the same call to newproc as the parent; * but in fact the code that runs is that of swtch. * The subtle implication of the returned value of swtch * (see above) is that this is the value that newproc's * caller in the new process sees. */ newproc() { int a1, a2; struct proc *p, *up; register struct proc *rpp; register *rip, n; struct proc *pend; p = NULL; /* * First, just locate a slot for a process * and copy the useful info from this process into it. * The panic "cannot happen" because fork has already * checked for the existence of a slot. */ retry: mpid++; if(mpid < 0) { mpid = 0; goto retry; } for(rpp = &proc[0]; rpp < &proc[NPROC]; rpp++) { if(rpp->p_stat == NULL){ if(p == NULL) p = rpp; }else pend = rpp; if ((rpp->p_pid==mpid)||(rpp->p_pgrp == mpid)) goto retry; } if ((rpp = p)==NULL) panic("no procs"); if(rpp>pend) pend = rpp; pend++; procend = pend; /* * make proc entry for new proc */ rip = u.u_procp; up = rip; rpp->p_stat = SRUN; rpp->p_clktim = 0; rpp->p_flag = SLOAD; rpp->p_uid = rip->p_uid; rpp->p_pgrp = rip->p_pgrp; rpp->p_nice = rip->p_nice; rpp->p_textp = rip->p_textp; rpp->p_pid = mpid; rpp->p_ppid = rip->p_pid; rpp->p_time = 0; rpp->p_cpu = 0; /* * make duplicate entries * where needed */ for(rip = &u.u_ofile[0]; rip < &u.u_ofile[NOFILE];) if((rpp = *rip++) != NULL) rpp->f_count++; for(rip = &u.u_semi4[0]; rip < &u.u_semi4[NOLOCK];) if((rpp = *rip++) != NULL) rpp->sem_cnt++; if((rpp=up->p_textp) != NULL) { rpp->x_count++; rpp->x_ccount++; } u.u_cdir->i_count++; u.u_rdir->i_count++; /* * Partially simulate the environment * of the new process so that when it is actually * created (by copying) it will look right. */ savu(u.u_rsav); rpp = p; u.u_procp = rpp; rip = up; n = rip->p_size; a1 = rip->p_addr; rpp->p_size = n; a2 = malloc(coremap, n); /* * If there is not enough core for the * new process, swap out the current process to generate the * copy. */ if(a2 == NULL) { rip->p_stat = SIDL; rpp->p_addr = a1; savu(u.u_ssav); xswap(rpp, 0, 0); rpp->p_flag =| SSWAP; rip->p_stat = SRUN; } else { /* * There is core, so just copy. */ rpp->p_addr = a2; while(n--) copyseg(a1++, a2++); } u.u_procp = rip; setrq(rpp); return(0); } /* * Change the size of the data+stack regions of the process. * If the size is shrinking, it's easy-- just release the extra core. * If it's growing, and there is core, just allocate it * and copy the image, taking care to reset registers to account * for the fact that the system's stack has moved. * If there is no core, arrange for the process to be swapped * out after adjusting the size requirement-- when it comes * in, enough core will be allocated. * Because of the ssave and SSWAP flags, control will * resume after the swap in swtch, which executes the return * from this stack level. * * After the expansion, the caller will take care of copying * the user's stack towards or away from the data area. */ expand(newsize) { int i, n; register *p, a1, a2; p = u.u_procp; n = p->p_size; p->p_size = newsize; a1 = p->p_addr; if(n >= newsize) { mfree(coremap, n-newsize, a1+newsize); return; } savu(u.u_rsav); a2 = malloc(coremap, newsize); if(a2 == NULL) { savu(u.u_ssav); xswap(p, 1, n); p->p_flag =| SSWAP; qswtch(); /* no return */ } p->p_addr = a2;  for(i=0; ip_addr); sureg(); } ck towards or away from the data area. */ expand(newsize) { int i, n; register *p, a1, a2; p = u.u_procp; n = p->p_size; p->p_size = newsize; a1 = p->p_addr; if(n >= newsize) { mfree(coremap, n-newsize, a1+newsize); return; } savu(u.u_rsav); a2 = malloc(coremap, newsize); if(a2 == NULL) { savu(u.u_ssav); xswap(p, 1, n); p->p_flag =| SSWAP; qswtch(); /* no return */ } p->p_addr = a2; # #include "../head/param.h" #include "../head/conf.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/systm.h" /* * Bmap defines the structure of file system storage * by returning the physical block number on a device given the * inode and the logical block number in a file. * When convenient, it also leaves the physical * block number of the next block of the file in rablock * for use in read-ahead. */ bmap(ip, bn) struct inode *ip; int bn; { register *bp, *bap, nb; int *nbp, d, i; d = ip->i_dev; if(bn & ~03777) { u.u_error = EFBIG; return(0); } if((ip->i_mode&ILARG) == 0) { /* * small file algorithm */ if((bn & ~7) != 0) { /* * convert small to large */ if ((bp = alloc(d)) == NULL) return(NULL); bap = bp->b_addr; for(i=0; i<8; i++) { *bap++ = ip->i_addr[i]; ip->i_addr[i] = 0; } ip->i_addr[0] = bp->b_blkno;  bdwrite(bp); ip->i_mode =| ILARG; ip->i_flag =| IUPD; goto large; } nb = ip->i_addr[bn]; if(nb == 0 && (bp = alloc(d)) != NULL) { bdwrite(bp); nb = bp->b_blkno; ip->i_addr[bn] = nb; ip->i_flag =| IUPD; } rablock = 0; if (bn<7) rablock = ip->i_addr[bn+1]; return(nb); } /* * large file algorithm */ large: i = bn>>8; if((nb=ip->i_addr[i]) == 0) { if ((bp = alloc(d)) == NULL) return(NULL); ip->i_addr[i] = bp->b_blkno; ip->i_flag =| IUPD; } else bp = bread(d, nb); bap = bp->b_addr; /* * normal indirect fetch */ i = bn & 0377; if((nb=bap[i]) == 0 && (nbp = alloc(d)) != NULL) { nb = nbp->b_blkno; bap[i] = nb; bdwrite(nbp); bdwrite(bp); } else brelse(bp); rablock = 0; if(i < 255) rablock = bap[i+1]; return(nb); } /* * Pass back c to the user at his location u_base; * update u_base, u_count, and u_offset. Return -1 * on the last character of the user's read. * u_base is in the user address space unless u_segflg is set.  */ passc(c) char c; { register id; if((id = u.u_segflg) == 1) *u.u_base = c; else if(id?suibyte(u.u_base, c):subyte(u.u_base, c) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++u.u_offset[1] == 0) u.u_offset[0]++; u.u_base++; return(u.u_count == 0? -1: 0); } /* * Pick up and return the next character from the user's * write call at location u_base; * update u_base, u_count, and u_offset. Return -1 * when u_count is exhausted. u_base is in the user's * address space unless u_segflg is set. */ cpass() { register c, id; if(u.u_count == 0) return(-1); if((id = u.u_segflg) == 1) c = *u.u_base; else if((c = id==0?fubyte(u.u_base):fuibyte(u.u_base)) < 0) { u.u_error = EFAULT; return(-1); } u.u_count--; if(++u.u_offset[1] == 0) u.u_offset[0]++; u.u_base++; return(c&0377); } /* * Routine which sets a user error; placed in * illegal entries in the bdevsw and cdevsw tables. */ nodev() { u.u_error = ENODEV; } /* * Null routine; placed in insignificant entries * in the bdevsw and cdevsw tables. */ nulldev() { return(0); /* make stty happy*/ } /* * copy count words from from to to. */ bcopy(from, to, count) int *from, *to; { register *a, *b, c; a = from; b = to; c = count; do *b++ = *a++; while(--c); } == 0) u.u_offset[0]++; u.u_base++; return(c&0377); } /* * Routine which sets a user error; placed in * illegal entries in the bdevsw and cdevsw tables. */ nodev() { u.u_error = ENODEV; } /* * Null routine; placed in insignif# #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/procx.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/reg.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/seg.h" /* * exec system call. */ exec(ip) struct inode *ip; { register nc; register char *cp; register struct buf *bp; int na, bno, ucp, ap, c; /* * Collect arguments on "file" in swap space. */ bp = 0; if(u.u_call == 0){ u.u_loc = 0; if((ip = gethead()) == NULL) return; } if (getxfile(ip) || u.u_error) goto bad; /* * copy back arglist */ na = u.u_narg; nc = u.u_nargc; bno = u.u_loc; bp = 0; ucp = -nc; ap = ucp - na*2 - 4; u.u_ar0[R6] = ap; suword(ap, na); nc = 0; while(na--) { suword(ap=+2, ucp); do { if ((nc&0777) == 0) { if (bp) brelse(bp); bp = bread(swapdev, bno+(nc>>9)); cp = bp->b_addr; } subyte(ucp++, (c = *cp++)); nc++;  } while(c&0377); } suword(ap+2, -1); setregs(); bad: if (bp) brelse(bp); if(bno) mfree(swapmap, (NCARGS+511)/512, bno); } /* * Read in and set up memory for executed file. * Zero return is normal; * non-zero means only the text is being replaced */ getxfile(ip) int *ip; { register ds, sep; int ts, ss, overlay, i; extern int uchar(); /* * find text and data sizes * try them out for possible * exceed of max sizes */ ts = ((u.u_exdata.ux_tsize+63)>>6) & 01777; if (u.u_exdata.ux_mag == 0405) { ds = u.u_dsize; ss = u.u_ssize; xfree(); xalloc(ip); u.u_ar0[R7] = u.u_exdata.ux_entloc & ~01; } else { ds = ((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize+63)>>6) & 01777; ss = SSIZE + (u.u_nargc>>6); /* * allocate and clear core * at this point, committed * to the new image */ u.u_prof[3] = 0; xfree(); i = USIZE+ds+ss; expand(i); while(--i >= USIZE) clearseg(u.u_procp->p_addr+i); xalloc(ip); /* * read in data segment */ estabur(0, ds, 0, 0, RO); u.u_base = 0; u.u_offset[1] = 020+u.u_exdata.ux_tsize; u.u_count = u.u_exdata.ux_dsize; readi(ip); /* * set SUID/SGID protections, if no tracing */ if ((u.u_procp->p_flag&STRC)==0) { if(ip->i_mode&ISUID) if(u.u_uid != 0) { u.u_uid = ip->i_uid; u.u_procp->p_uid = ip->i_uid; } if(ip->i_mode&ISGID) u.u_gid = ip->i_gid; } } u.u_tsize = ts; u.u_dsize = ds; u.u_ssize = ss; u.u_sep = (u.u_exdata.ux_mag == 0411)?1:0; u.u_dev = ip->i_dev; u.u_inode = ip->i_number; estabur(ts, ds, ss,u.u_sep,RO); bad: iput(ip); return(u.u_exdata.ux_mag == 0405?1:0); } /* * Clear registers on exec */ setregs() { register int *rp; register char *cp; register i; for(rp = &u.u_signal[0]; rp < &u.u_signal[NSIG]; rp++) if(((*rp & 1) == 0)||(u.u_call)) *rp = 0; for(rp = &u.u_semi4[0]; rp < &u.u_semi4[NOLOCK]; rp++) if(*rp) freesem(rp); for(cp = ®loc[0]; cp < ®loc[6];) u.u_ar0[*cp++] = 0; u.u_ar0[R7] = u.u_exdata.ux_entloc & ~01; for(rp = &u.u_fsav[0]; rp < &u.u_fsav[25];) *rp++ = 0; for (rp = &u.u_ofile[FCLFILE]; rp < &u.u_ofile[NOFILE];) { closef(*rp); *rp++ = NULL; } /* * Remember file name for accounting. */ u.u_acflag =& ~1; for (i=0; ip_flag =& ~STRC; p->p_clktim = 0; for(a = &u.u_signal[0]; a < &u.u_signal[NSIG];) *a++ = 1; for(a = &u.u_ofile[0]; a < &u.u_ofile[NOFILE]; a++) if (*a) { closef(*a); *a = NULL; } for(a = &u.u_semi4[0]; a < &u.u_semi4[NOLOCK]; a++) if(*a) freesem(a); if(u.u_msgqhdr != NULL) msgflush(); plock(u.u_cdir); iput(u.u_cdir); plock(u.u_rdir); iput(u.u_rdir); xfree(); acct(); mfree(coremap, p->p_size, p->p_addr); p->p_stat = SZOMB; p->xp_xstat = u.u_arg[0]; p->xp_utime = u.u_cutime + u.u_utime; p->xp_stime = u.u_cstime + u.u_stime; for(q = &proc[0]; q < procend; q++) if(q->p_ppid == p->p_pid) { q->p_ppid = 1; if(q->p_stat == SZOMB) psignal(&proc[1], SIGCLD); if (q->p_stat==SSTOP) setrun(q); } for(q = &proc[0]; q < procend; q++) if(p->p_ppid == q->p_pid) { psignal(q, SIGCLD); swtch(); /* no return */ } printf("Init proc dead"); swtch(); } /* * Wait system call.  * Search for a terminated (zombie) child, * finally lay it to rest, and collect its status. * Look also for stopped (traced) children, * and pass back status from them. */ wait() { register f; register struct proc *p; loop: f = 0; for(p = &proc[0]; p < procend; p++) if(p->p_ppid == u.u_procp->p_pid) { f++; if(p->p_stat == SZOMB) { freeproc(p, 1); return; } if(p->p_stat == SSTOP) { if((p->p_flag&SWTED) == 0) { p->p_flag =| SWTED; u.u_ar0[R0] = p->p_pid; u.u_ar0[R1] = (fsig(p)<<8) | 0177; return; } continue; } } if(f) { sleep(u.u_procp, PWAIT); goto loop; } u.u_error = ECHILD; } /* * Dispose of zombie children by removing them * from the process table. */ freeproc(p, flg) register struct proc *p; { if(flg) { u.u_ar0[R0] = p->p_pid; u.u_ar0[R1] = p->xp_xstat; } u.u_cutime =+ p->xp_utime; u.u_cstime =+ p->xp_stime; p->p_stat = NULL; p->p_pid = 0; p->p_ppid = 0; p->p_sig = 0; p->p_pgrp = 0; p->p_flag = 0; p->p_wchan = 0; } /* * fork system call. */ fork() { register struct proc *p1, *p2; register a; /* * Make sure there's enough swap space for max * core image, thus reducing chances of running out */ if ((a = malloc(swapmap, ctob(MAXMEM))) == 0) { u.u_error = ENOMEM; goto out; } mfree(swapmap, ctob(MAXMEM), a); p1 = u.u_procp; for(p2 = &proc[0]; p2 < &proc[NPROC]; p2++) if(p2->p_stat == NULL) goto found; u.u_error = EAGAIN; goto out; found: if(newproc()) { u.u_ar0[R0] = p1->p_pid; u.u_start = time; u.u_cstime = 0; u.u_stime = 0; u.u_cutime = 0; u.u_utime = 0; u.u_msgqhdr = NULL; u.u_acflag =| 1; return(0); } u.u_ar0[R0] = p2->p_pid; out: u.u_ar0[R7] =+ 2; return(1); } /* * break system call. * -- bad planning: "break" is a dirty word in C. */ sbreak() { register a, n, d; int i; /* * set n to new data size * set d to new-old * set n to new total size */ n = (((u.u_arg[0]+63)>>6) & 01777); if(!u.u_sep) n =- ctos(u.u_tsize) * 128; if(n < 0) n = 0; d = n - u.u_dsize; n =+ USIZE+u.u_ssize; if(estabur(u.u_tsize, u.u_dsize+d, u.u_ssize, u.u_sep, RO)) return; u.u_dsize =+ d; if(d > 0) goto bigger; a = u.u_procp->p_addr + n - u.u_ssize; i = n; n = u.u_ssize; while(n--) { copyseg(a-d, a); a++; } expand(i); return; bigger: expand(n); a = u.u_procp->p_addr + n; n = u.u_ssize; while(n--) { a--; copyseg(a-d, a); } while(d--) clearseg(--a); } scall() { extern int uchar(); register struct inode *ip; u.u_loc = 0; if(( ip= gethead()) == NULL)  return; u.u_call = 1; if(fork() == 0){ exec(ip); }else{ if(u.u_error){ iput(ip); } } u.u_call = 0; return; } execarg() { int na, bno, ucp, ap, c; register nc; register char *cp; register struct buf *bp; na = 0; nc = 0; u.u_narg = 0; u.u_nargc = 0; if ((bno = malloc(swapmap,(NCARGS+511)/512)) == 0) panic("Out of swap"); bp = 0; if (u.u_arg[1]) while(ap = fuword(u.u_arg[1])) { na++; if(ap == -1) u.u_error = EFAULT; u.u_arg[1] =+ 2; do { if (nc >= NCARGS-1) u.u_error = E2BIG; if ((c = fubyte(ap++)) < 0) u.u_error = EFAULT; if (u.u_error) goto bad; if ((nc&0777) == 0) { if (bp) bawrite(bp); bp = getblk(swapdev, bno+(nc>>9)); cp = bp->b_addr; } nc++; *cp++ = c; } while (c>0); } if (bp) bawrite(bp); bp = 0; if((nc&1) != 0) nc++; u.u_narg = na; u.u_nargc = nc; u.u_loc = bno; return(0); bad: if(bp) brelse(bp); if(bno) mfree(swapmap, (NCARGS+511)/512, bno); return(1); } gethead() { register struct inode *ip; register ds, sep; int ts, ss, overlay, i; extern int uchar(); if ((ip = namei(uchar, 0)) == NULL) return(NULL); if(access(ip, IEXEC)) goto bad; if((ip->i_mode & IFMT) != 0 || (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) { u.u_error = EACCES; goto bad; } /* * read in first few bytes * of file for segment * sizes: * ux_mag = 407/410/411/405 * 407 is plain executable * 410 is RO text * 411 is separated ID * 405 is overlaid text */ u.u_base = &u.u_exdata; u.u_count = sizeof(u.u_exdata); u.u_offset[1] = 0; u.u_offset[0] = 0; u.u_segflg = 1; readi(ip); u.u_segflg = 0; if(u.u_error) goto bad; if (u.u_count!=0) { u.u_error = ENOEXEC; goto bad; } sep = 0; overlay = 0; if(u.u_exdata.ux_mag == 0407) { u.u_exdata.ux_dsize =+ u.u_exdata.ux_tsize; u.u_exdata.ux_tsize = 0; } else if (u.u_exdata.ux_mag == 0411) sep++; else if (u.u_exdata.ux_mag == 0405) overlay++; else if (u.u_exdata.ux_mag != 0410) { u.u_error = ENOEXEC; goto bad; } if(u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) { u.u_error = ETXTBSY; goto bad; } if(execarg()) goto bad; ts = ((u.u_exdata.ux_tsize+63)>>6) & 01777; if(overlay) { if (u.u_sep==0 && ctos(ts) != ctos(u.u_tsize) || u.u_nargc) { u.u_error = ENOMEM; goto bad; } } else { ds = ((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize+63)>>6) & 01777; ss = SSIZE + (u.u_nargc>>6); if(checkur(ts,ds,ss,sep)) goto bad; } return(ip); bad: iput(ip); return(NULL); } oto bad; } if# #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/reg.h" #include "../head/file.h" #include "../head/filex.h" #include "../head/inode.h" #include "../head/inodex.h" /* * read system call */ read() { rdwr(FREAD); } /* * write system call */ write() { rdwr(FWRITE); } /* * common code for read and write calls: * check permissions, set base, count, and offset, * and switch out to readi, writei, or pipe code. */ rdwr(mode) { register *fp, *ip, m; m = mode; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if((fp->f_flag&m) == 0) { u.u_error = EBADF; return; } u.u_base = u.u_arg[0]; u.u_count = u.u_arg[1]; u.u_segflg = 0; if(fp->f_flag&FPIPE) { if(m==FREAD) readp(fp); else writep(fp); } else { ip = fp->f_inode; u.u_offset[1] = fp->f_offset[1]; u.u_offset[0] = fp->f_offset[0]; if((ip->i_mode&(IFCHR&IFBLK)) == 0) plock(ip); if(m==FREAD) readi(ip); else writei(ip); if((ip->i_mode&(IFCHR&IFBLK)) == 0) prele(ip); dpadd(fp->f_offset, u.u_arg[1]-u.u_count); } u.u_ar0[R0] = u.u_arg[1]-u.u_count; } /* * open system call */ open() { register *ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; u.u_arg[1]++; open1(ip, u.u_arg[1], 0); } /* * creat system call */ creat() { register *ip; extern uchar; ip = namei(&uchar, 1); if(ip == NULL) { if(u.u_error) return; ip = maknode(u.u_arg[1]&07777&(~ISVTX)); if (ip==NULL) return; open1(ip, FWRITE, 2); } else open1(ip, FWRITE, 1); } /* * common code for open and creat. * Check permissions, allocate an open file structure, * and call the device open routine if any. */ open1(ip, mode, trf) int *ip; { register struct file *fp; register *rip, m; int i; rip = ip; m = mode; if(trf != 2) { if(m&FREAD) access(rip, IREAD); if(m&FWRITE) { access(rip, IWRITE); if((rip->i_mode&IFMT) == IFDIR) u.u_error = EISDIR; } } if(u.u_error) goto out; if(trf) itrunc(rip); prele(rip); if ((fp = falloc()) == NULL) goto out; fp->f_flag = m&(FREAD|FWRITE); fp->f_inode = rip; i = u.u_ar0[R0]; openi(rip, m&(FWRITE|FREAD)); if(u.u_error == 0) return; u.u_ofile[i] = NULL; fp->f_count--; out: iput(rip); } /* * close system call */ close() { register *fp; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; u.u_ofile[u.u_ar0[R0]] = NULL; closef(fp); } /* * seek system call */ seek() { int n[2]; register *fp, t; fp = getf(u.u_ar0[R0]); if(fp == NULL) return; if(fp->f_flag&FPIPE) { u.u_error = ESPIPE; return; } t = u.u_arg[1]; if(t > 2) { n[1] = u.u_arg[0]<<9; n[0] = u.u_arg[0]>>7; if(t == 3) n[0] =& 0777; } else { n[1] = u.u_arg[0]; n[0] = 0; if(t!=0 && n[1]<0) n[0] = -1; } switch(t) { case 1: case 4: n[0] =+ fp->f_offset[0]; dpadd(n, fp->f_offset[1]); break; default: n[0] =+ fp->f_inode->i_size0&0377; dpadd(n, fp->f_inode->i_size1); case 0: case 3: ; } if (n[0] & ~0777) u.u_error = EFBIG; else { fp->f_offset[1] = n[1]; fp->f_offset[0] = n[0]; } } /* * Tell -- discover offset of file R/W pointer */ tell() { register struct file *fp; if (fp = getf(u.u_ar0[R0])) { u.u_ar0[R0] = fp->f_offset[0]; u.u_ar0[R1] = fp->f_offset[1]; } } /* * link system call */ link() { register *ip, *xp; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; if(ip->i_nlink >= 127) { u.u_error = EMLINK; goto out; } if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; /* * Unlock to avoid possibly hanging the namei. * Sadly, this means races. (Suppose someone * deletes the file in the meantime?) * Nor can it be locked again later * because then there will be deadly * embraces. */ prele(ip); u.u_dirp = u.u_arg[1]; xp = namei(&uchar, 1); if(xp != NULL) { u.u_error = EEXIST; iput(xp); } if(u.u_error) goto out; if(u.u_pdir->i_dev != ip->i_dev) { iput(u.u_pdir); u.u_error = EXDEV; goto out; } wdir(ip); ip->i_nlink++; ip->i_flag =| IUPD; out: iput(ip); } /* * mknod system call */ mknod() { register *ip; extern uchar; if(suser()) { ip = namei(&uchar, 1); if(ip != NULL) { u.u_error = EEXIST; goto out; } } if(u.u_error) return; ip = maknode(u.u_arg[1]); if (ip==NULL) return; ip->i_addr[0] = u.u_arg[2]; out: iput(ip); } /* * sleep system call * not to be confused with the sleep internal routine. */ sslep() { long d; spl7(); d = time + u.u_ar0[R0]; while (time < d) { if (tout<=time || d>6)) access(ip, IREAD); if (u.u_arg[1]&(IWRITE>>6)) access(ip, IWRITE); if (u.u_arg[1]&(IEXEC>>6)) access(ip, IEXEC); iput(ip); } u.u_uid = svuid; u.u_gid = svgid; } < d) { if (tout<=time || df_inode, u.u_arg[0]); if(fp->f_flag&FPIPE) { /* compute correct pipe length */ ip = fp->f_inode; suword(save+10, ip->i_size1-fp->f_offset[1]); } } /* * the stat system call. */ stat() { register ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; stat1(ip, u.u_arg[1]); iput(ip); } /* * The basic routine for fstat and stat: * get the inode and pass appropriate parts back. */ stat1(ip, ub) int *ip; { register i, *bp, *cp; iupdat(ip); bp = bread(ip->i_dev, ldiv(ip->i_number+31, 16)); cp = bp->b_addr + 32*lrem(ip->i_number+31, 16) + 24; ip = &(ip->i_dev); for(i=0; i<14; i++) { if (suword(ub, *ip) != *ip++) u.u_error = EFAULT; ub =+ 2; } for(i=0; i<4; i++) { if (suword(ub, *cp) != *cp++) u.u_error = EFAULT; ub =+ 2; } brelse(bp); } /* * the dup system call. */ dup() { register i, *fp; fp = getf(u.u_ar0[R0].lobyte); if(fp == NULL) return; i = u.u_ar0[R0].hibyte & 0377; if ((i > NOFILE) || ((i = ufalloc(i)) < 0)) return; u.u_ofile[i] = fp; fp->f_count++; } /* * the mount system call. */ /* * the mount system call. */ smount() { int d; register *ip; register struct mount *mp, *smp; extern uchar; d = getmdev(); if(u.u_error) return; u.u_dirp = u.u_arg[1]; ip = namei(&uchar, 0); if(ip == NULL) return; if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0) goto out; smp = NULL; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) { if(mp->m_bufp != NULL) { if(d == mp->m_dev) goto out; } else if(smp == NULL) smp = mp; } if(smp == NULL) goto out; (*bdevsw[d.d_major].d_open)(d, !u.u_arg[2]); if(u.u_error) goto out; mp = bread(d, 1); if(u.u_error) { brelse(mp); goto out1; } smp->m_inodp = ip; smp->m_dev = d; smp->m_bufp = getblk(NODEV); bcopy(mp->b_addr, smp->m_bufp->b_addr, 256); smp = smp->m_bufp->b_addr; smp->s_ilock = 0; smp->s_flock = 0; smp->s_ronly = u.u_arg[2] & 1; brelse(mp); ip->i_flag =| IMOUNT; prele(ip); return; out: u.u_error = EBUSY; out1: iput(ip); } /* * the umount system call. */ sumount() { int d; register struct inode *ip; register struct mount *mp; update(); d = getmdev(); if(u.u_error) return; for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) if(mp->m_bufp!=NULL && d==mp->m_dev) goto found; u.u_error = EINVAL; return; found: for(ip = &inode[0]; ip < &inode[NINODE]; ip++) if(ip->i_number!=0 && d==ip->i_dev) { u.u_error = EBUSY; return; } (*bdevsw[d.d_major].d_close)(d, 0); ip = mp->m_inodp; ip->i_flag =& ~IMOUNT; plock(ip); iput(ip); ip = mp->m_bufp; mp->m_bufp = NULL; brelse(ip); } /* * Common code for mount and umount. * Check that the user's argument is a reasonable * thing on which to mount, and return the device number if so. */ getmdev() { register d, *ip; extern uchar; if(!suser()) return; ip = namei(&uchar, 0); if(ip == NULL) return(NODEV); if((ip->i_mode&IFMT) != IFBLK) u.u_error = ENOTBLK; d = ip->i_addr[0]; if(ip->i_addr[0].d_major >= nblkdev) u.u_error = ENXIO; iput(ip); return(d); } ); iput(ip); ip = mp->m_bufp# /* * Everything in this file is a routine implementing a system call. */ #include "../head/param.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/reg.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/systm.h" #include "../head/proc.h" #include "../head/procx.h" getswit() { u.u_ar0[R0] = SW->integ; } gtime() { u.u_ar0[R0] = time.hiword; u.u_ar0[R1] = time.loword; } stime() { if(suser()) { logtchg(); time.hiword = u.u_ar0[R0]; time.loword = u.u_ar0[R1]; wakeup(&tout); } } setuid() { register uid; uid = u.u_ar0[R0].lobyte; if(u.u_ruid == uid.lobyte || suser()) { u.u_uid = uid; u.u_procp->p_uid = uid; u.u_ruid = uid; } } getuid() { u.u_ar0[R0] = u.u_ruid&0377; } setgid() { register gid; gid = u.u_ar0[R0].lobyte; if(u.u_rgid == gid.lobyte || suser()) { u.u_gid = gid; u.u_rgid = gid; } } getgid() { u.u_ar0[R0] = u.u_rgid&0377; } getpid() /* get own and parent process id */ { u.u_ar0[R0] = u.u_procp->p_pid; u.u_ar0[R1] = u.u_procp->p_ppid; } sync() { update(); } nice() { register n; n = u.u_ar0[R0]; if(n > 20) n = 20; if(n < 0 && !suser()) n = 0; u.u_procp->p_nice = n; } /* * Unlink system call. * Hard to avoid races here, especially * in unlinking directories. */ unlink() { register *ip, *pp; extern uchar; pp = namei(&uchar, 2); if(pp == NULL) return; /* * Check for unlink(".") * to avoid hanging on the iget */ if (pp->i_number != u.u_dent.u_ino) ip = iget(pp->i_dev, u.u_dent.u_ino); else { ip = pp; ip->i_count++; } if(ip == NULL) goto out1; if((ip->i_mode&IFMT)==IFDIR && !suser()) goto out; /* * Don't unlink a mounted file. */ if (ip->i_dev != pp->i_dev) { u.u_error = EBUSY; goto out; } if (ip->i_flag&ITEXT && ip->i_nlink==1) { u.u_error = ETXTBSY; goto out; } u.u_offset[1] =- DIRSIZ+2; u.u_base = &u.u_dent; u.u_count = DIRSIZ+2; u.u_dent.u_ino = 0; writei(pp); ip->i_nlink--; ip->i_flag =| IUPD; out: iput(ip); out1: iput(pp); } chdir() { register *ip; extern uchar; ip = namei(&uchar, 0); if(ip == NULL) return; if((ip->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; bad: iput(ip); return; } if(access(ip, IEXEC)) goto bad; prele(ip); plock(u.u_cdir); iput(u.u_cdir); u.u_cdir = ip; } chmod() { register *ip; if ((ip = owner()) == NULL) return; ip->i_mode =& ~07777; if (u.u_uid) u.u_arg[1] =& ~ISVTX; ip->i_mode =| u.u_arg[1]&07777; ip->i_flag =| IUPD; iput(ip); } chown() { register *ip; if (!suser() || (ip = owner()) == NULL) return; ip->i_uid = u.u_arg[1].lobyte; ip->i_gid = u.u_arg[1].hibyte; ip->i_flag =| IUPD; iput(ip); } ssig() { register a; register struct proc *p; a = u.u_arg[0]; if(a<=0 || a>=NSIG || a==SIGKIL) { u.u_error = EINVAL; return; } u.u_ar0[R0] = u.u_signal[a]; u.u_signal[a] = u.u_arg[1]; u.u_procp->p_sig =& ~(1L<<(a-1)); if(a == SIGCLD) { a = u.u_procp->p_pid; for(p = &proc[0]; p < &proc[NPROC]; p++) if(a == p->p_ppid && p->p_stat == SZOMB) psignal(u.u_procp, SIGCLD); } } kill() { register struct proc *p, *q; register a; int f; f = 0; a = u.u_ar0[R0]; q = u.u_procp; for(p = &proc[0]; p < &proc[NPROC]; p++) { if(a != 0 && p->p_pid != a) continue; if(a == 0 && (p->p_pgrp != q->p_pgrp || p <= &proc[1])) continue; if(u.u_uid != 0 && u.u_uid != p->p_uid) continue; f++; psignal(p, u.u_arg[0]); } if(f == 0) u.u_error = ESRCH; } times() { register *p; for(p = &u.u_utime; p < &u.u_utime+4;) { suword(u.u_arg[0], *p++); u.u_arg[0] =+ 2; } } profil() { u.u_prof[0] = u.u_arg[0] & ~1; /* base of sample buf */ u.u_prof[1] = u.u_arg[1]; /* size of same */ u.u_prof[2] = u.u_arg[2]; /* pc offset */ u.u_prof[3] = (u.u_arg[3]>>1) & 077777; /* pc scale */ } /* * alarm clock signal */ alarm() { register c, *p; p = u.u_procp; c = p->p_clktim; p->p_clktim = u.u_ar0[R0]; u.u_ar0[R0] = c; } /* * indefinite wait. * no one should wakeup(&u) */ pause() { for(;;) sleep(&u, PSLEP); } chroot() { register *oldroot, *ip; extern uchar; if (!suser()) return; oldroot = u.u_rdir; u.u_rdir = rootdir; ip = namei(&uchar, 0); if (ip == NULL) goto poor; if ((ip->i_mode&IFMT) != IFDIR) { u.u_error = ENOTDIR; bad: iput(ip); poor: u.u_rdir = oldroot; return; } u.u_rdir = ip; iput(oldroot); prele(ip); } u.u_procp; c = p->p_clktim; p->p_clktim = u.u_ar0[R0]; u.u_ar0[R0] = c; } /* * indefinite wait. * no one should wakeup(&u) */ pause() { for(;;) sleep(&u, PSLEP); } chroot() { register *oldroot, *ip; extern uch#include "../head/param.h" #include "../head/reg.h" #include "../head/ipcomm.h" #include "../head/ipcommx.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" /* * Semaphore System Call */ lflags() { register struct semi4s *sp, **p; register int n; if((n = u.u_arg[1]) >= NLOCK) { u.u_error = EINVAL; return; } if(n < 0) sp = NULL; else sp = &semi4s[n]; switch(u.u_arg[0].lobyte) { default: u.u_error = EINVAL; return; case ASEMI: if(sp == NULL) { /*dynamic alloc*/ for(sp = &semi4s[0]; sp < &semi4s[NLOCK]; sp++) if(sp->sem_cnt == 0) { alocsem(sp); return; } u.u_error = ETABLE; } else if(usemf(sp) == NULL) alocsem(sp); else u.u_error = ENOALOC; /*already alloc*/ return; case FSEMI: if(sp == NULL) { u.u_error = ENOALOC; for(p = &u.u_semi4[0];p < &u.u_semi4[NOLOCK]; p++) if(*p) { freesem(p); u.u_error = 0; } } else if((p = usemf(sp)) != NULL) freesem(p); else u.u_error = ENOALOC; return; case LOCK: case UNLOCK: case TLOCK: n = S_LU; break; case P: case V: case TEST: n = S_PV; } /*ensure semi4 is alloc for purpose intended*/ if(sp == NULL) { u.u_error = EINVAL; return; } if(usemf(sp) == NULL || (sp->sem_flag & S_TYPE) != n) { u.u_error = ENOALOC; return; } u.u_ar0[R0] = sp->sem_lock; switch(u.u_arg[0].lobyte) { case LOCK: if(sp->sem_lock == u.u_procp->p_pid) return; while(sp->sem_lock != 0) { sp->sem_flag =| IP_WANTED; sleep(sp, PSEMI4); } u.u_ar0[R0] = sp->sem_lock; sp->sem_lock = u.u_procp->p_pid; return; case UNLOCK: if(sp->sem_lock != u.u_procp->p_pid) u.u_error = EFUNC; else { sp->sem_lock = 0; if(sp->sem_flag & IP_WANTED) { sp->sem_flag =& ~IP_WANTED; wakeup(sp); } } return; case TLOCK: if(sp->sem_lock == 0) sp->sem_lock = u.u_procp->p_pid; return; case P: while(sp->sem_lock <= 0) { sp->sem_flag =| IP_WANTED; sleep(sp, PSEMI4); } u.u_ar0[R0] = sp->sem_lock; sp->sem_lock--; return; case V: sp->sem_lock++; if(sp->sem_flag & IP_WANTED) { sp->sem_flag =& ~IP_WANTED; wakeup(sp); } return; case TEST: if(sp->sem_lock > 0) sp->sem_lock--; } } /* * Free a semaphore */ freesem(up) int **up; { register struct semi4s *rsp; rsp = *up; /* unlock l-u semi4 if necessary */ if(((rsp->sem_flag & S_TYPE) == S_LU) && (rsp->sem_lock == u.u_procp->p_pid)) { rsp->sem_lock = 0; if(rsp->sem_flag & IP_WANTED) { rsp->sem_flag =& ~IP_WANTED; wakeup(rsp); } } rsp->sem_cnt--; *up = NULL; } /* * See if the semaphore "sp" is already allocated * by a process. Note that NULL is a suitable argument. */ usemf(sp) struct semi4s *sp; { register struct semi4s *rsp, **p; rsp = sp; for(p = &u.u_semi4[0]; p < &u.u_semi4[NOLOCK]; p++) if(rsp == *p) return(p); return(NULL); } /* * Allocate the semaphore "sp". */ alocsem(sp) struct semi4s *sp; { register struct semi4s *rsp; struct semi4s **p; register int type, scope; if((p = usemf(NULL)) == NULL) { u.u_error = ETABLE; return; } rsp = sp; switch(scope = u.u_arg[0].hibyte) { default: u.u_error = EINVAL; return; case 0: case 1: case 2: type = S_LU; break; case 3: case 4: case 5: type = S_PV; scope =- 3; } if(rsp->sem_cnt == 0) { rsp->sem_flag = type | scope; rsp->sem_lock = 0; rsp->sem_id = ipidtyp(scope); } else if((rsp->sem_flag & S_TYPE) != type) u.u_error = ENOALOC; else ipacces(&rsp->sem_flag); if(u.u_error) return; rsp->sem_cnt++; *p = rsp; u.u_ar0[R0] = rsp - &semi4s[0]; } /* * Verify that a process has permission to access an * interprocess communication resource. */ ipacces(p) struct ipaword *p; { register int scope, id; register struct ipaword *rp; rp = p; scope = rp->ip_flag & IP_PERM; if(u.u_uid == 0 || scope == IP_ANY) return(1); id = rp->ip_id & 0377; if(id == ipidtyp(scope)) return(1); u.u_error = EACCES; return(0); } /* * Determine the appropriate id to to used * in checking acces permission. */ ipidtyp(scope) { switch(scope) { case IP_ANY: return(0); case IP_UID: return(u.u_uid&0377); case IP_GID: return(u.u_gid&0377); } u.u_error = EINVAL; return(0); } ct ipaword *p; { register int scope, id; register struct ipaword *rp; rp = p; scope = rp->ip_flag & IP_PERM; if(u.u_uid == 0 || scope == IP_ANY) return(1); id = rp->ip_id & 0377; if(id == ipidtyp(scope)) return(1); u.u_error = EACCES; return(0); } /* * Determine the appropriate id to to used * in checkin# /* * This table is the switch used to transfer * to the appropriate routine for processing a system call. * Each row contains the number of arguments expected * and a pointer to the routine. */ int sysent[] { 0, &nullsys, /* 0 = indir */ 0, &rexit, /* 1 = exit */ 0, &fork, /* 2 = fork */ 2, &read, /* 3 = read */ 2, &write, /* 4 = write */ 2, &open, /* 5 = open */ 0, &close, /* 6 = close */ 0, &wait, /* 7 = wait */ 2, &creat, /* 8 = creat */ 2, &link, /* 9 = link */ 1, &unlink, /* 10 = unlink */ 2, &exec, /* 11 = exec */ 1, &chdir, /* 12 = chdir */ 0, >ime, /* 13 = time */ 3, &mknod, /* 14 = mknod */ 2, &chmod, /* 15 = chmod */ 2, &chown, /* 16 = chown */ 1, &sbreak, /* 17 = break */ 2, &stat, /* 18 = stat */ 2, &seek, /* 19 = seek */ 0, &getpid, /* 20 = getpid */ 3, &smount, /* 21 = mount */ 1, &sumount, /* 22 = umount */ 0, &setuid, /* 23 = setuid */ 0, &getuid, /* 24 = getuid */ 0, &stime, /* 25 = stime */ 3, &ptrace, /* 26 = ptrace */ 0, &alarm, /* 27 = alarm */ 1, &fstat, /* 28 = fstat */ 0, &pause, /* 29 = pause */ 1, &nullsys, /* 30 = smdate; inoperative */ 1, &stty, /* 31 = stty */ 1, >ty, /* 32 = gtty */ 2, &saccess, /* 33 = access */ 0, &nice, /* 34 = nice */ 0, &sslep, /* 35 = sleep */ 0, &sync, /* 36 = sync */ 1, &kill, /* 37 = kill */ 0, &getswit, /* 38 = switch */ 0, &nullsys, /* 39 = setpgrp (not in yet) */ 0, &tell, /* 40 = tell */ 0, &dup, /* 41 = dup */ 0, &pipe, /* 42 = pipe */ 1, ×, /* 43 = times */ 4, &profil, /* 44 = prof */ 0, &nosys, /* 45 = tiu */ 0, &setgid, /* 46 = setgid */ 0, &getgid, /* 47 = getgid */ 2, &ssig, /* 48 = sig */ 4, &messag, /* 49 = message */ 1, &serrlog, /* 50 = error logging */ 1, &sysacct, /* 51 = turn acct off/on */ 0, &nosys, /* 52 = x */ 0, &nosys, /* 53 = x */ 2, &ioctl, /* 54 = ioctl */ 0, &nosys, /* 55 = x */ 0, &nosys, /* 56 = x */ 2, &scall, /* 57 = scall */ 0, &nosys, /* 58 = x */ 0, &nosys, /* 59 = x */ 1, &chroot, /* 60 = chroot */ 0, &nosys, /* 61 = x */ 2, &lflags, /* 62 = lock */ 0, &nosys /* 63 = x */ }; /* * Dummy entry for illegal system calls */ int badent[] { 0, &nosys }; e */ 1, &serrlog, /* 50 = error logging */ 1, &sysacct, /* 51 = turn acct off/on */ 0, &nosys, /* 52 = x */ 0, &nosys, /* 53 = x */ 2, &ioctl, /* 54 = ioctl */ 0, &nosys, /* 55 = x */ 0, &nosys, /* 56 = x */ 2, &scall, /* 57 = scall */ 0, &# #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/text.h" #include "../head/textx.h" #include "../head/inode.h" #include "../head/inodex.h" #include "../head/buf.h" #include "../head/bufx.h" #include "../head/seg.h" /* * Swap out process p. * The ff flag causes its core to be freed-- * it may be off when called to create an image for a * child process in newproc. * Os is the old size of the data area of the process, * and is supplied during core expansion swaps. * * panic: out of swap space */ xswap(p, ff, os) int *p; { register *rp, a; rp = p; if(os == 0) os = rp->p_size; a = malloc(swapmap, ctob(rp->p_size)); if(a == NULL) panic("out of swap space"); rp->p_flag =| SLOCK; xccdec(rp->p_textp); swap(a, rp->p_addr, os, B_WRITE); if(ff) mfree(coremap, os, rp->p_addr); rp->p_addr = a; rp->p_flag =& ~(SLOAD|SLOCK); rp->p_time = 0; if(runout) { runout = 0; wakeup(&runout); } } /* * relinquish use of the shared text segment * of a process. */ xfree() { register struct text *xp; register struct inode *ip; if((xp=u.u_procp->p_textp) == NULL) return; xlock(xp); xp->x_flag =& ~XLOCK; ip = xp->x_iptr; if(--xp->x_count==0 && (ip->i_mode&ISVTX)==0) { xp->x_iptr = NULL; mfree(swapmap, ctob(xp->x_size), xp->x_daddr); mfree(coremap, xp->x_size, xp->x_caddr); ip->i_flag =& ~ITEXT; if (ip->i_flag&ILOCK) ip->i_count--; else iput(ip); } else xccdec(xp); u.u_procp->p_textp = NULL; } /* * Attach to a shared text segment. * If there is no shared text, just return. * If there is, hook up to it: * if it is not currently being used, it has to be read * in from the inode (ip); the written bit is set to force it * to be written out as appropriate. * If it is being used, but is not currently in core, * a swap has to be done to get it back. */ xalloc(ip) int *ip; { register struct text *xp; register *rp, ts; if(u.u_exdata.ux_tsize == 0) return; rp = NULL;  for (xp = &text[0]; xp < &text[NTEXT]; xp++) { if(xp->x_iptr == NULL) { if(rp == NULL) rp = xp; continue; } if(xp->x_iptr == ip) { xlock(xp); xp->x_count++; u.u_procp->p_textp = xp; if (xp->x_ccount == 0) xexpand(xp); else xp->x_ccount++; xunlock(xp); return; } } if((xp=rp) == NULL) { printf("out of text"); psignal(u.u_procp, SIGKIL); return; } xp->x_flag = XLOAD|XLOCK; xp->x_count = 1; xp->x_ccount = 0; xp->x_iptr = rp = ip; rp->i_flag =| ITEXT; rp->i_count++; ts = ((u.u_exdata.ux_tsize+63)>>6) & 01777; xp->x_size = ts; if((xp->x_daddr = malloc(swapmap, ctob(ts))) == NULL) panic("out of swap space"); u.u_procp->p_textp = xp; xexpand(xp); estabur(ts, 0, 0, 0, RW); u.u_count = u.u_exdata.ux_tsize; u.u_offset[0] = 0; u.u_offset[1] = 020; u.u_base = 0; u.u_segflg = 2; u.u_procp->p_flag =| SLOCK; readi(rp); u.u_procp->p_flag =& ~SLOCK; u.u_segflg = 0; xp->x_flag = XWRIT; } /* * Assure core for text segment * Text must be locked to keep someone else from * freeing it in the meantime. * x_ccount must be 0. */ xexpand(axp) struct text *axp; { register struct text *xp; xp = axp; if ((xp->x_caddr = malloc(coremap, xp->x_size)) != NULL) { if ((xp->x_flag&XLOAD)==0) swap(xp->x_daddr, xp->x_caddr, xp->x_size, B_READ); xp->x_ccount++; xunlock(xp); return; } savu(u.u_rsav); savu(u.u_ssav); xswap(u.u_procp, 1, 0); xunlock(xp); u.u_procp->p_flag =| SSWAP; qswtch(); /* no return */ } /* * Lock and unlock a text segment from swapping */ xlock(axp) { register struct text *xp; xp = axp; while(xp->x_flag&XLOCK) { xp->x_flag =| XWANT; sleep(xp, PSWP); } xp->x_flag =| XLOCK; } xunlock(axp) { register struct text *xp; xp = axp; if (xp->x_flag&XWANT) wakeup(xp); xp->x_flag =& ~(XLOCK|XWANT); } /* * Decrement the in-core usage count of a shared text segment. * When it drops to zero, free the core space. */ xccdec(axp) struct text *axp; { register struct text *xp; if ((xp = axp)==NULL || xp->x_ccount==0) return; xlock(xp); if (--xp->x_ccount==0) { if (xp->x_flag&XWRIT) { xp->x_flag =& ~XWRIT; swap(xp->x_daddr,xp->x_caddr,xp->x_size,B_WRITE); } mfree(coremap, xp->x_size, xp->x_caddr); } xunlock(xp); } xp; if (xp->x_flag&XWANT) wakeup(xp); xp->x_flag =& ~(XLOCK|XWANT); } /* * Decrement the in-core usage count of a shared text segment. * When it drops to zero, free the core space. */ xccdec(axp) struct text *axp; { register struct text *xp; if ((xp = axp)==NULL || xp->x_ccount==0)# #include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/proc.h" #include "../head/reg.h" #include "../head/seg.h" #define EBIT 1 /* user error bit in PS: C-bit */ #define UMODE 0170000 /* user-mode bits in PS word */ #define SETD 0170011 /* SETD instruction */ #define SYS 0104400 /* sys (trap) instruction */ #define USER 020 /* user-mode flag added to dev */ #define MEMORY 0177740 /* 11/70 "memory" subsystem */ #define NSYSENT 64  /* number of syscall entries */ /* * structure of the system entry table (sysent.c) */ struct sysent { int count; /* argument count */ int (*call)(); /* name of handler */ } sysent[NSYSENT]; /* * Dummy entry for illegal system calls */ struct sysent badent[1]; /* * Offsets of the user's registers relative to * the saved r0. See reg.h */ char regloc[9] { R0, R1, R2, R3, R4, R5, R6, R7, RPS }; /* * Called from l40.s or l45.s when a processor trap occurs. * The arguments are the words saved on the system stack * by the hardware and software during the trap processing. * Their order is dictated by the hardware and the details * of C's calling sequence. They are peculiar in that * this call is not 'by value' and changed user registers * get copied back on return. * dev is the kind of trap that occurred. */ trap(dev, sp, r1, nps, r0, pc, ps) { register i, a; register struct sysent *callp; savfp(); if ((ps&UMODE) == UMODE) dev =| USER; u.u_ar0 = &r0; switch(dev) { /* * Trap not expected. * Usually a kernel mode bus error. * The numbers printed are used to * find the hardware PS/PC as follows. * (all numbers in octal 18 bits) * address_of_saved_ps = * (ka6*0100) + aps - 0140000; * address_of_saved_pc = * address_of_saved_ps - 2; */ default: printf("ka6 = %o\n", *ka6); printf("aps = %o\n", &ps); printf("trap type %o\n", dev); panic("trap"); case 0+USER: /* bus error */ i = SIGBUS; break; /* * If illegal instructions are not * being caught and the offending instruction * is a SETD, the trap is ignored. * This is because C produces a SETD at * the beginning of every program which * will trap on CPUs without 11/45 FPU. */ case 1+USER: /* illegal instruction */ if(fuiword(pc-2) == SETD && u.u_signal[SIGINS] == 0) goto out; i = SIGINS; break; case 2+USER: /* bpt or trace */ i = SIGTRC; break; case 3+USER: /* iot */ i = SIGIOT; break; case 5+USER: /* emt */ i = SIGEMT; break; case 6+USER: /* sys call */ u.u_error = 0; ps =& ~EBIT; if((i=fuiword(pc-2)&0377) < NSYSENT) callp = &sysent[i]; else callp = badent; if (callp == sysent) { /* indirect */ a = fuiword(pc); pc =+ 2; i = fuword(a); if((i&(~0377)) != SYS || (i =& 0377) >= NSYSENT) callp = badent; /* illegal */ else callp = &sysent[i]; for(i=0; icount; i++) u.u_arg[i] = fuword(a =+ 2); } else { for(i=0; icount; i++) { u.u_arg[i] = fuiword(pc); pc =+ 2; } } u.u_dirp = u.u_arg[0]; trap1(callp->call); if(u.u_intflg) u.u_error = EINTR; if(u.u_error < 100) { if(u.u_error) { ps =| EBIT; r0 = u.u_error; } goto out; } i = SIGSYS; break; /* * Since the floating exception is an * imprecise trap, a user generated * trap may actually come from kernel * mode. In this case, a signal is sent * to the current process to be picked * up later. */ case 8: /* floating exception */ psignal(u.u_procp, SIGFPT); return; case 8+USER: i = SIGFPT; break; /* * If the user SP is below the stack segment, * grow the stack automatically. * This relies on the ability of the hardware * to restart a half executed instruction. * On the 11/40 this is not the case and * the routine backup/l40.s may fail. * The classic example is on the instruction * cmp -(sp),-(sp) */ case 9+USER: /* segmentation exception */ a = sp; if(backup(u.u_ar0) == 0) if(grow(a)) goto out; i = SIGSEG; break; /* * The code here is a half-hearted * attempt to do something with all * of the 11/70 parity registers. * In fact, there is little that * can be done. */ case 10: case 10+USER: printf("parity\n"); if(cputype == 70) { for(i=0; i<4; i++) printf("%o ", MEMORY->r[i]); printf("\n"); MEMORY->r[2] = -1; if(dev & USER) { i = SIGBUS; break; } } panic("parity"); /* * Locations 0-2 specify this style trap, since * DEC hardware often generates spurious * traps through location 0. This is a * symptom of hardware problems and may * represent a real interrupt that got * sent to the wrong place. Watch out * for hangs on disk completion if this message appears. */ case 15: case 15+USER: printf("Random interrupt ignored\n"); return; } psignal(u.u_procp, i); out: if(issig()) psig(); curpri = setpri(u.u_procp); } /* * Call the system-entry routine f (out of the * sysent table). This is a subroutine for trap, and * not in-line, because if a signal occurs * during processing, an (abnormal) return is simulated from * the last caller to savu(qsav); if this took place * inside of trap, it wouldn't have a chance to clean up. * * If this occurs, the return takes place without * clearing u_intflg; if it's still set, trap * marks an error which means that a system * call (like read on a typewriter) got interrupted * by a signal. */ trap1(f) int (*f)(); { u.u_intflg = 1; savu(u.u_qsav); (*f)(); u.u_intflg = 0; } /* * Stray interrupt in low core. */ stray(dev) { printf("stray interrupt at %o\n",(4*dev)); } /* * nonexistent system call-- set fatal error code. */ nosys() { u.u_error = 100; } /* * Ignored system call */ nullsys() { } , the return takes place without * clearing u_intflg; if it's still set, trap * marks an error which means that a system * call (like read on a typewriter) got interrupted * by a signal. */ trap1(f) int (*f)(); { u.u_intflg = 1; savu(u.u_qsav); (*f)(); u.u_intflg = 0; } /* * Stray interrupt in low core. */ stray(dev) { printf("stray interru/* * Fake semaphores for 11/40s */ lflags() { nosys(); } freesem() { } . */ nosys() { u.u_error = 100; } /* * Ignored system call */ nullsys() { } , the return takes place without * clearing u_intflg; if it's still set, trap * marks an error which means that a system * call (like read on a typewriter) got interrupted * by a signal. */ trap1(f) int (*f)(); { u.u_intflg = 1; savu(u.u_qsav); (*f)(); u.u_intflg = 0; } /* * Stray interrupt in low core. */ stray(dev) { printf("stray interru#include "../head/param.h" #include "../head/systm.h" #include "../head/user.h" #include "../head/userx.h" #include "../head/buf.h" #include "../head/conf.h" #include "../head/ipcomm.h" #include "../head/proc.h" #include "../head/reg.h" #include "../head/elog.h" #define ESTART 1 #define EEND 0 #define SSR3 0172516 /* Memory Management Register 3 */ struct msgqhdr *logqp; /* message queue header of logger */ struct msghdr *lasterr; struct errtab *errtabs[]; /* pointers to device errtabs */ int mmemwant, msgcore[]; /* interface to messages */ /* * Error logging system call * Activates and terminates error logging after ensuring * that all the prerequisites are met. */ serrlog() { register struct msgqhdr *qp; register struct msghdr *mp; register struct estart *esp; if(!suser()) return; if((qp = u.u_msgqhdr) == NULL) { u.u_error = ENOALOC; return; } switch(u.u_arg[0]) { case ESTART: if(logqp != NULL) { if(qp != logqp) u.u_error = EBUSY; return; } while((mp = msgsetup(sizeof(*esp))) == NULL) { mmemwant++; sleep(msgcore, PMSG-1); /* grab space first */ } esp = &mp[1]; esp->es_cpu = cputype; if(cputype == 40) esp->es_mmr3 = 0; else esp->es_mmr3 = SSR3->integ; esp->es_nbdev = nblkdev; esp->es_ncdev = nchrdev; clrstat(&esp->es_conf); logqp = qp; /* starts logging */ logmsg(mp, E_GO); return; case EEND: if(qp != logqp) u.u_error = EFUNC; else termlog(); return; } u.u_error = EINVAL; } /* * When error logging is started, clrstat examines all the * device errtabs. It clears all the IO statistics for * any devices that keeps such records. An additional * responsibility is to fill in the system configuration portion * of the error log startup record. */ clrstat(cp) int *cp; { register struct errtab **ep; register int c, *p; struct iostat ios[0]; cp->e_bconf = 0; cp->e_cconf = 0; for(ep = errtabs; *ep; ep++) { c = (1<<(*ep)->e_devnum.d_major); switch((*ep)->e_devtyp&E_TYPE) { case E_BLK: cp->e_bconf =| c; break; case E_CHR: cp->e_cconf =| c; } if((p = (*ep)->e_iostat) != NULL) { c = (sizeof(ios[0])/2)*((*ep)->e_nunit); do *p++ = 0; while(--c); } } } /* * Whenever the system's concept of the time of day is * changed, an error log entry showing the old and the new * time iw written by logtchg. */ logtchg() { register struct msghdr *mp; struct etchg etp[0]; if(logqp) { if((mp = msgsetup(sizeof(etp[0]))) != NULL) { (&mp[1])->e_ntime.hiword = u.u_ar0[R0]; (&mp[1])->e_ntime.loword = u.u_ar0[R1]; logmsg(mp, E_TCHG); } } } /* * Sends error message type "type" to the error logging process. * Time stamps all such messages. */ logmsg(mp, type) register struct msghdr *mp; { mp->mq_sender = 0; mp->mq_type = E_NOACK; /* no ack on message */ (&mp[1])->e_type = type; (&mp[1])->e_ctime = time; msgsend(logqp, mp); } /* * Log an actual error for the device whose errtab is pointed to * by "ep". The "sclass" argument allows the driver to * attach a suffix to the error log entry type. */ logerr(ep, sclass) register struct errtab *ep; { if(ep->e_emsg != NULL) { logmsg(ep->e_emsg, (ep->e_devtyp&E_TYPE)|sclass); ep->e_emsg = NULL; } } /* * Perform the actual work of terminating error logging. * Any pending error messages and a stop message are sent * to the logger. */ termlog() { register struct errtab **ep; register int *ip; struct eend eep[0]; spl6(); /* ensure no one sneaks in */ for(ep = errtabs; *ep; ep++) { if((*ep)->e_emsg != NULL) logerr(*ep, E_EARLY); } if((ip = msgsetup(sizeof(eep[0]))) != NULL) logmsg(ip, E_STOP); logqp = NULL; /* stops logging */ spl0(); } /* * Format a block device error record */ fmtblk(ep, devloc, nregs, bp) int *devloc; register struct errtab *ep; register struct buf *bp; { register struct eblock *ebp; struct msghdr *mp; struct iostat ios[0]; if(logqp == NULL) return; if((mp = ep->e_emsg) != NULL) { (&mp[1])->e_rtry++; return; } if(cputype != 70 && ep->e_devtyp&E_RH70) nregs =- 2; /* no bae or cs3 on non 70s */ if((mp = msgsetup(sizeof(*ebp)+(nregs<<1))) == NULL) { ep->e_aunit->io_unlog++; return; } ebp = &mp[1]; ebp->e_dev = ep->e_devnum; /* "true" major + minor */ bcopy(ep->e_aunit, &ebp->e_stat, sizeof(ios[0])/2); ebp->e_bacty = blkacty; ebp->e_cacty = chracty; ebp->e_rtry = 0; ebp->e_nreg = nregs; ebp->e_rloc = devloc; bcopy(devloc, &ebp[1], nregs); ebp->e_dev.d_minor = bp->b_dev.d_minor; ebp->eb_bflg = bp->b_flags; ebp->eb_wcnt = bp->b_wcount; ebp->eb_maddr.hiword = bp->b_xmem; ebp->eb_maddr.loword = bp->b_addr; ebp->eb_bno = bp->b_blkno; ep->e_emsg = mp; lasterr = mp; } turn; } ebp = &mp[1]; ebp->e_dev = ep->e_devnum; /* "true" major + minor */ bcopy(ep->e_aunit, &ebp->e_stat, sizeof(ios[0])/2); ebp->e_bacty = blkacty; ebp->e_cacty = chracty; ebp->e_rtry = 0; ebp->e_nreg = nregs; ebp->e_rloc = devloc; bcopy(devloc, &ebp[1], nregs); ebp->e_dev.d_minor = bp->b_dev.d_minor; ebp->eb_bflg = bp->b_flags; ebp->eb_wcnt = bp-/* * Fake error logging functions for 11/40s */ serrlog() { nosys(); } logtchg() { } logerr() { } termlog() { } fmtblk() { } terr = mp; } turn; } ebp = &mp[1]; ebp->e_dev = ep->e_devnum; /* "true" major + minor */ bcopy(ep->e_aunit, &ebp->e_stat, sizeof(ios[0])/2); ebp->e_bacty = blkacty; ebp->e_cacty = chracty; ebp->e_rtry = 0; ebp->e_nreg = nregs; ebp->e_rloc = devloc; bcopy(devloc, &ebp[1], nregs); ebp->e_dev.d_minor = bp->b_dev.d_minor; ebp->eb_bflg = bp->b_flags; ebp->eb_wcnt = bp-calloc(n, s) { return(alloc(n*s)); } r 11/40s */ serrlog() { nosys(); } logtchg() { } logerr() { } termlog() { } fmtblk() { } terr = mp; } turn; } ebp = &mp[1]; ebp->e_dev = ep->e_devnum; /* "true" major + minor */ bcopy(ep->e_aunit, &ebp->e_stat, sizeof(ios[0])/2); ebp->e_bacty = blkacty; ebp->e_cacty = chracty; ebp->e_rtry = 0; ebp->e_nreg = nregs; ebp->e_rloc = devloc; bcopy(devloc, &ebp[1], nregs); ebp->e_dev.d_minor = bp->b_dev.d_minor; ebp->eb_bflg = bp->b_flags; ebp->eb_wcnt = bp-# include "../portc1/ciodec.c" cclose (fn) int fn; { struct fileps *fp; extern char *IEH3olbf[10]; if (fn < 0 || fn > 20) return; fp = &IEH3fpts[fn]; if (fp->nchars > 0 || fp->wrflag == 3) switch (fp->wrflag) { case 3: seek(fn,0,2); case 2: write (fn, fp->buff, fp->nchars); break; case 1: seek(fn, -(fp->nchars), 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,0,0}; ude "../portc1/ciodec.c" cclose (fn) int fn; { struct fileps *fp; extern char *IEH3olbf[10]; if (fn < 0 || fn > 20) return; fp = &IEH3fpts[fn]; if (fp->nchars > 0 || fp->wrflag == 3) switch (fp->wrflag) { case 3: seek(fn,0,2); case 2: write (fn, fp->buff, fp->nchars); break; case 1: seek(fn, -(fp->nchars), 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,# include "../portc1/ciodec.c" ceof (fn) int fn; { struct fileps *fp; fp = &IEH3fpts[fn]; if (fp->wrflag > 0 && fp->eoferr == 2) return(1); else return(0); } cerr (fn) int fn; { struct fileps *fp; fp = &IEH3fpts[fn]; if (fp->eoferr == 0) fp->eoferr = 1; if (fp->wrflag > 0 && fp->eoferr == 3) return(1); else return(0); } , 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,IEH3err (message, a, b, c, d, e) char message[]; { extern int cgoof; printf(2,"ERROR "); printf(2,message, a, b, c, d, e); cputc('\n', 2); cexit(cgoof); } cgoof 127; fn; { struct fileps *fp; fp = &IEH3fpts[fn]; if (fp->eoferr == 0) fp->eoferr = 1; if (fp->wrflag > 0 && fp->eoferr == 3) return(1); else return(0); } , 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,IEH3err (message, a, b, c, d, e) char message[]; { extern int cgoof; printf(2,"ERROR "); printf(2,message, a, b, c, d, e); cputc('\n', 2); cexit(cgoof); } cgoof 127; fn; { struct fileps *fp; fp = &IEH3fpts[fn]; if (fp->eoferr == 0) fp->eoferr = 1; if (fp->wrflag > 0 && fp->eoferr == 3) return(1); else return(0); } , 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,cexit (rcode) { /* closes all files and exits */ int i; for (i = 0; i < 10; i++) cclose(i); IEH3exit(rcode); } , b, c, d, e); cputc('\n', 2); cexit(cgoof); } cgoof 127; fn; { struct fileps *fp; fp = &IEH3fpts[fn]; if (fp->eoferr == 0) fp->eoferr = 1; if (fp->wrflag > 0 && fp->eoferr == 3) return(1); else return(0); } , 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,# include "../portc1/ciodec.c" cflush (fn) int fn; { struct fileps *fp; if (fn < 0 || fn >15) return; fp = &IEH3fpts[fn]; if (fp->nchars > 0 && fp->wrflag >= 2) { write (fn, fp->buff,fp->nchars); fp->bptr = fp->buff; fp -> nchars = fp->eoferr = 0; } if (fp->wrflag == 1) seek(fn, -(fp->nchars),1); return; } urn(0); } , 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,cfree (ptr) { free(ptr); } .c" cflush (fn) int fn; { struct fileps *fp; if (fn < 0 || fn >15) return; fp = &IEH3fpts[fn]; if (fp->nchars > 0 && fp->wrflag >= 2) { write (fn, fp->buff,fp->nchars); fp->bptr = fp->buff; fp -> nchars = fp->eoferr = 0; } if (fp->wrflag == 1) seek(fn, -(fp->nchars),1); return; } urn(0); } , 1); } fp -> nchars = fp->eoferr = 0; fp -> wrflag = 0; if ( IEH3olbf[fn] != 0 && fp->bsize >4) free(IEH3olbf[fn]); IEH3olbf[fn] = 0; close (fn); } char *IEH3olbf[10] {0,0,0,0,0,0,0,0,# include "../portc1/ciodec.c" char cgetc(fn) { struct fileps *fp; if (fn <0 || fn >15) IEH3err("cgetc: %d illegal file number",fn); fp = &IEH3fpts[fn]; if (fp == 0 || fp->wrflag > 1) IEH3err("cgetc: %d not open to read",fn); if (fp->wrflag == 0) /* file not opened with fopen: try making a buffer */ IEH3mbuf (fn, 0); if (fp->eoferr > 1) return ('\0'); if (fp->nchars == 0) switch (fp->nchars = read(fn, fp->bptr=fp->buff, fp->bsize)) { case -1: /* error */ if (fp->eoferr == 0) IEH3err("cgetc: error on %d",fn); fp->eoferr = 3; return ('\0'); case 0: fp->eoferr = 2; return ('\0'); } fp->nchars--; return (*(fp->bptr++)); } cin 0; ; if (fp == 0 || fp->wrflag > 1) IEH3err("cgetc: %d not open to read",fn); if (fp->wrflag == 0) /* file not opened with fopen: try making a buffer */ IEH3mbuf (fn, 0); if (fp->eoferr > 1) return ('\0'); if (fp->nchars == 0) switch (fp->nchars = read(fn, fp->bptr=fp->buff, fp->bsize)) { case -1: /* error */ if (fp->eoferr == 0) IEH3err("cgetcstruct fileps { char *buff, *bptr; int nchars, bsize; char eoferr, wrflag; }; extern struct fileps IEH3fpts[10]; return (*(fp->bptr++)); } cin 0; ; if (fp == 0 || fp->wrflag > 1) IEH3err("cgetc: %d not open to read",fn); if (fp->wrflag == 0) /* file not opened with fopen: try making a buffer */ IEH3mbuf (fn, 0); if (fp->eoferr > 1) return ('\0'); if (fp->nchars == 0) switch (fp->nchars = read(fn, fp->bptr=fp->buff, fp->bsize)) { case -1: /* error */ if (fp->eoferr == 0) IEH3err("cgetc_clenf (s) /* counts length of string */ char *s; { int n; for (n=0; *s++ != '\0'; n++); return (n);} s IEH3fpts[10]; return (*(fp->bptr++)); } cin 0; ; if (fp == 0 || fp->wrflag > 1) IEH3err("cgetc: %d not open to read",fn); if (fp->wrflag == 0) /* file not opened with fopen: try making a buffer */ IEH3mbuf (fn, 0); if (fp->eoferr > 1) return ('\0'); if (fp->nchars == 0) switch (fp->nchars = read(fn, fp->bptr=fp->buff, fp->bsize)) { case -1: /* error */ if (fp->eoferr == 0) IEH3err("cgetccopen (filename, type) char *filename; int type; { int fn; switch (type) { case 'r': type = 0; case 0: fn = open(filename,0); break; case 'a': type = 2; case 2: if ((fn=open(filename,1))>=0) break; /* courtesy of sny */ /* append defaults to write if file missing */ case 'w': type = 1; case 1: fn = creat(filename,0666); break; default: IEH3err("copen: bad file %s",filename); } if (fn >= 0) IEH3mbuf(fn,type); return(fn); } case -1: /* error */ if (fp->eoferr == 0) IEH3err("cgetc# include "../portc1/ciodec.c" char cputc(ch, fn) { struct fileps *fp; if (fn<0 || fn>20) return(ch); fp = &IEH3fpts[fn]; if (fp->wrflag == 1) IEH3err("cputc: %d not open",fn); if (fp->wrflag == 0) IEH3mbuf(fn,1); *(fp->bptr++) = ch; if (++(fp->nchars) < fp->bsize) return(ch); if (fp->wrflag == 3) /* append, seek to end */ { seek(fn, 0, 2); fp->wrflag = 2; /* now just write from here on */ } if ( write(fn, fp->bptr=fp->buff, fp->nchars) < 0) { if (fp->eoferr == 0) IEH3err("cputc: writing %d",fn); fp->eoferr = 3; } fp->nchars = 0; return (ch); } cout 1; ileps *fp; if (fn<0 || fn>20) return(ch); fp = &IEH3fpts[fn]; if (fp->wrflag == 1) IEH3err("cputc: %d not open",fn); if (fp->wrflag == 0) IEH3mbuf(fn,1); *(fp->bptr++) = ch; if (++(fp->nchars) < fp->bsize) return(ch); if (fp->wrflag == 3) /* append, seek to end */ { seek(fn, 0, 2); fp->wrflag = 2; /* now just write from here on */ } if ( write(fn, fp->bptr=fp->buff, fp->nchars) < 0) { if (fp->eoferr == 0) IEH3err("cputc: writing %d",fn);cwrite (buff, buffp1, len, fn) char *buff, *buffp1; int len, fn; { int unit, nwr; unit = buffp1; if (unit > 100 || unit < 0) unit = buffp1-buff; len =* unit; nwr = write (fn, buff, len); return (nwr < 0 ? -1 : nwr/unit); } cread (buff, buffp1, len, fn) char *buff, *buffp1; int len, fn; { int unit, nrd; unit = buffp1; if (unit >100 || unit < 0) unit = buffp1 - buff; len =* unit; nrd = read(fn, buff, len); return (nrd < 0 ? -1 : nrd/unit); } ) < 0) { if (fp->eoferr == 0) IEH3err("cputc: writing %d",fn);exit(x) { cexit(x); } len, fn) char *buff, *buffp1; int len, fn; { int unit, nwr; unit = buffp1; if (unit > 100 || unit < 0) unit = buffp1-buff; len =* unit; nwr = write (fn, buff, len); return (nwr < 0 ? -1 : nwr/unit); } cread (buff, buffp1, len, fn) char *buff, *buffp1; int len, fn; { int unit, nrd; unit = buffp1; if (unit >100 || unit < 0) unit = buffp1 - buff; len =* unit; nrd = read(fn, buff, len); return (nrd < 0 ? -1 : nrd/unit); } ) < 0) { if (fp->eoferr == 0) IEH3err("cputc: writing %d",fn);ftoa (x, str, prec, format) float x; char *str; { /* converts a floating point number to an ascii string */ /* x is stored into str, which should be at least 30 chars long */ int ie, i, k, ndig, fstyle; double y; ndig = ( prec<0) ? 7 : (prec > 22 ? 23 : prec+1); if (format == 'f' || format == 'F') fstyle = 1; else fstyle = 0; /* print in e format unless last arg is 'f' */ ie = 0; /* if x negative, write minus and reverse */ if ( x < 0) { *str++ = '-'; x = -x; } /* put x in range 1 <= x < 10 */ if (x > 0.0) while (x < 1.0) { x =* 10.0; ie--; } while (x >= 10.0) { x = x/10.0; ie++; } /* in f format, number of digits is related to size */ if (fstyle) ndig =+ ie; /* round. x is between 1 and 10 and ndig will be printed to right of decimal point so rounding is ... */ y = 10.0; for (i = 0; i < ndig; i++) y = y/10.; x =+ y/2.; if (x >= 10.0) /* repair rounding disasters */ { x = 1.0; ie++; if (fstyle) ndig++; } /* now loop. put out a digit (obtain by multiplying by 10, truncating, subtracting) until enough digits out */ /* if fstyle, and leading zeros, they go out special */ if (fstyle && ie < 0) { *str++ = '0'; i = (ndig > 0) ? -1 : (ndig-1); i =- ie; if (i > 0) { *str++ = '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *str++ = 'E'; if (ie < 0) { ie = -ie; *str++ = '-'; } for (k=100; k > ie; k =/10); for (; k > 0; k =/10) { *str++ = ie/k + '0'; ie = ie%k; } } *str = '\0'; return; } '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *stgetchar() { extern cin; return (cgetc(cin)); } *str++ = '-'; } for (k=100; k > ie; k =/10); for (; k > 0; k =/10) { *str++ = ie/k + '0'; ie = ie%k; } } *str = '\0'; return; } '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *stgets (s) char *s; { /* gets (s) - read a string with cgetc and store in s */ char *p; extern int cin; p=s; while ((*s = cgetc(cin)) != '\n' && *s != '\0') s++; if (*p == '\0') return (0); *s = '\0'; return (p); } } '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *stgetvec (n) { return (alloc(n)); } read a string with cgetc and store in s */ char *p; extern int cin; p=s; while ((*s = cgetc(cin)) != '\n' && *s != '\0') s++; if (*p == '\0') return (0); *s = '\0'; return (p); } } '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *st/ C library -- exit / exit(code) / code is return in r0 to system .globl _IEH3exit _IEH3exit: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 sys exit = '\0') s++; if (*p == '\0') return (0); *s = '\0'; return (p); } } '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *stintss() { int a[3]; if (gtty(0,a) == 0) return(1); return(0); } m .globl _IEH3exit _IEH3exit: mov r5,-(sp) mov sp,r5 mov 4(r5),r0 sys exit = '\0') s++; if (*p == '\0') return (0); *s = '\0'; return (p); } } '.'; while (i--) *str++ = '0'; } } for (i=0; i < ndig; i++) { if (i == (fstyle ? ie+1 : 1)) /* where is decimal point */ *str++ = '.'; k = x; *str++ = k + '0'; x =- (y=k); x =* 10.0; } /* now, in estyle, put out exponent if not zero */ if (!fstyle && ie != 0) { *st# include "../portc1/ciodec.c" IEH3bsz 512; IEH3mbuf (fn, type) int fn, type; { struct fileps *fp; extern char *IEH3olbf[], *alloc(); extern int IEHfbak[10]; int bx[19], size, bloc; struct{ char lobyte; char hibyte; }; int ln; fp = &IEH3fpts[fn]; fp->eoferr = fp->nchars = 0; fp->wrflag = type+1; /* decide whether to buffer or not */ ln = lnxx(fn); if (ln.lobyte != 'x' || ln.hibyte != 'x') size = 1; else if (fstat(fn,bx) > 0 && bx[0] == 40 && type == 0) size = 1; else size = IEH3bsz; for (fp->buff = 0; size >10 && fp->buff == 0; size =/ 4) if ((bloc = alloc(size+100)) != -1) { IEH3olbf[fn] = bloc; fp->buff = fp->bptr =bloc + 100; fp->bsize = size; break; } if (fp->buff == 0) { fp->buff = fp->bptr = &IEHfbak[fn]; fp->bsize = size>1 ? 2 : 1; } } struct fileps IEH3fpts [10]; int IEHfbak[10]; to buffer or not */ ln = lnxx(fn); if (ln.lobyte != 'x' || ln.hibyte != 'x') size = 1; else if (fstat(fn,bx) > 0 && bx[0] == 40 && type == 0) size = 1; else size = IEH3bsz; for (fp->buff = 0char IEH3endm[128] {0}; IEH3mtab (formatp) char **formatp; { /* make up special table of string ending characters */ int i, normal; char ch; /* normally all characters end string except those listed */ normal = 1; if (**formatp == '^') {normal = 0; (*formatp)++;} for (i= 0; i < 128; i++) IEH3endm[i] = normal; while ((ch = *((*formatp)++)) != ']') IEH3endm[ch] = !IEH3endm[ch]; } te != 'x') size = 1; else if (fstat(fn,bx) > 0 && bx[0] == 40 && type == 0) size = 1; else size = IEH3bsz; for (fp->buff = 0int yyportlib 1; ] {0}; IEH3mtab (formatp) char **formatp; { /* make up special table of string ending characters */ int i, normal; char ch; /* normally all characters end string except those listed */ normal = 1; if (**formatp == '^') {normal = 0; (*formatp)++;} for (i= 0; i < 128; i++) IEH3endm[i] = normal; while ((ch = *((*formatp)++)) != ']') IEH3endm[ch] = !IEH3endm[ch]; } te != 'x') size = 1; else if (fstat(fn,bx) > 0 && bx[0] == 40 && type == 0) size = 1; else size = IEH3bsz; for (fp->buff = 0char *_ptrbf, *_ptrst, *__fmt; printf(a1,a2,a3,a4){ auto char c, *s, adj, *ptr,*p, buf[30]; int lnflg; extern cputc(),_putstr(), cout; auto int *adx, x, n, m, width, prec,i, padchar, fd; double *dblptr; int *lngptr, longdata; char (*f)(); _ptrbf = buf; fd=cout; adx = &a1; f = cputc; if (a1 == -1) { f = _putstr; _ptrst = a2; adx =+ 2; } else if (a1 >= 0 && a1 <= 9) fd = *adx++; __fmt = *adx++; while( c = *__fmt++ ){ if(c != '%') (*f)(c,fd); else { x = *adx++; if( *__fmt == '-' ){ adj = 'l'; __fmt++; } else adj = 'r'; padchar = (*__fmt=='0') ? '0' : ' '; width = __conv(); if( *__fmt == '.'){++__fmt; prec = __conv();} else prec = -1; s = lnflg = 0; swc: switch ( c = *__fmt++ ) { case 'u': case 'U': _prtone(x, c, 10); break; case 'd': case 'D': lnflg ? _prtl(longdata) : _prtone(x,c,10); break; case 'l': case 'L': lnflg = 1; lngptr = adx++ -1; longdata = *lngptr; goto swc; case 'o': case 'O': lnflg ? _prls(longdata, c, 7, 3) : _prtone(x,c,8); break; case 'x': case 'X': lnflg ? _prls (longdata, c,15,4) : _prtone(x,c,16); break; case 'S': case 's': s=x; break; case 'C': case 'c': *_ptrbf++ = x&0777; break; case 'E': case 'e': case 'F': case 'f': dblptr = adx-1; adx =+ 3; ftoa (*dblptr, s=buf, prec, c); prec = -1; break; default: (*f)(c,fd); adx--; } if (s == 0) {*_ptrbf = '\0'; s = buf;} n = _clenf (s); n = (prec= 0) ? prec : n; m = width-n; if (adj == 'r') { if (padchar=='0' && s[0] == '-') { n--; (*f)(*s++,fd); } while (m-- > 0) (*f)(padchar,fd); } while (n--) (*f)(*s++,fd); while (m-- > 0) (*f)(padchar,fd); _ptrbf = buf; } } if(a1 == -1) (*f)('\0',fd); } __conv() { auto c,n; n = 0; while( ((c = *__fmt++) >= '0') && (c<='9')) n = n*10+c-'0'; __fmt--; return(n); } _putstr(chr,str){ *_ptrst++ = chr; return; } _prtone(n, format, base) { int digs[15], *dpt, k; extern int ldivr; dpt = digs; if (n<0 && format == 'd') {n = -n; *_ptrbf++ = '-';} while (n!=0) { n = ldiv(0,n,base); *dpt++ = ldivr; } if (dpt == digs) *dpt++ = 0; while (dpt != digs) { k = *--dpt; *_ptrbf++ = k + ((k<=9) ? '0' : ( (format== 'x') ? 'a'-10 : 'A'-10)); } } _prtl(n) int n; { int digs[15], *dpt; dpt = digs; if (n>=0) n= -n; else *_ptrbf++ = '-'; for(; n!= 0; n=n/10) *dpt++ = n%10; if (dpt==digs) *dpt++ = 0; while (dpt != digs) *_ptrbf++ = '0' - *--dpt; } _prls (n, format, mask, shift) int n; { int digs[15], *dpt, k; int bigmask; bigmask = 1; bigmask = bigmask << (32-shift); bigmask = bigmask -1; for(dpt=digs; n != 0; n= (n>>shift)&bigmask) *dpt++ = n&mask; if (dpt==digs) *dpt++ = 0; while (dpt != digs) { k = *--dpt; *_ptrbf++ = k + ( (k<=9) ? '0' : ( (format=='x') ? 'a'-10 : 'A'-10)); } } n>=0) n= -n; else *_ptrbf++ = '-'; for(; n!= 0; n=n/10) *dpt++ = n%10; if (dpt==digs) *dpt++ = 0; while (dpt != digs) *_ptrbf++ = '0' - *--dpt; } _pputchar (c) char c; { extern cout; cputc(c,cout); } , *dpt, k; int bigmask; bigmask = 1; bigmask = bigmask << (32-shift); bigmask = bigmask -1; for(dpt=digs; n != 0; n= (n>>shift)&bigmask) *dpt++ = n&mask; if (dpt==digs) *dpt++ = 0; while (dpt != digs) { k = *--dpt; *_ptrbf++ = k + ( (k<=9) ? '0' : ( (format=='x') ? 'a'-10 : 'A'-10)); } } n>=0) n= -n; else *_ptrbf++ = '-'; for(; n!= 0; n=n/10) *dpt++ = n%10; if (dpt==digs) *dpt++ = 0; while (dpt != digs) *_ptrbf++ = '0' - *--dpt; } _pputs(str) char *str; { auto char *p,c; auto int f; extern int cout; p = str; while( (c = *p++)!= '\0') cputc(c,cout); cputc('\n',cout); return(str); } r(dpt=digs; n != 0; n= (n>>shift)&bigmask) *dpt++ = n&mask; if (dpt==digs) *dpt++ = 0; while (dpt != digs) { k = *--dpt; *_ptrbf++ = k + ( (k<=9) ? '0' : ( (format=='x') ? 'a'-10 : 'A'-10)); } } n>=0) n= -n; else *_ptrbf++ = '-'; for(; n!= 0; n=n/10) *dpt++ = n%10; if (dpt==digs) *dpt++ = 0; while (dpt != digs) *_ptrbf++ = '0' - *--dpt; } _prelvec (ptr) { free(ptr); } char *p,c; auto int f; extern int cout; p = str; while( (c = *p++)!= '\0') cputc(c,cout); cputc('\n',cout); return(str); } r(dpt=digs; n != 0; n= (n>>shift)&bigmask) *dpt++ = n&mask; if (dpt==digs) *dpt++ = 0; while (dpt != digs) { k = *--dpt; *_ptrbf++ = k + ( (k<=9) ? '0' : ( (format=='x') ? 'a'-10 : 'A'-10)); } } n>=0) n= -n; else *_ptrbf++ = '-'; for(; n!= 0; n=n/10) *dpt++ = n%10; if (dpt==digs) *dpt++ = 0; while (dpt != digs) *_ptrbf++ = '0' - *--dpt; } _p# include "../portc1/ciodec.c" rew(fn) { struct fileps *fp; if(fn<0 || fn>14) return; fp = &IEH3fpts[fn]; if (fp==0 || fp->wrflag < 1) return; /* change append to normal open */ switch (fp->wrflag) { case 3: /* append, change to write */ fp->wrflag = 2; return; case 2: /* write */ cflush(fn); case 1: /* read */ fp->nchars = 0; fp->eoferr = 0; seek(fn, 0, 0); return; } } -'; for(; n!= 0; n=n/10) *dpt++ = n%10; if (dpt==digs) *dpt++ = 0; while (dpt != digs) *_ptrbf++ = '0' - *--dpt; } _pscanf (p1, p2, p3, p4) int p1, p2, p3, p4; { /* first arg can be a control string, a file id, or -1 */ int ptrs[10], j, ip, flp, k; char *np; extern int cin; extern (*_Igetc)(), (*_Iungc)(), cgetc(), ungetc(), _Igstr(), _Iungs(); extern char *_Iinpt; ip = 0; if (p1 == -1) {k = 1; _Iinpt = p2;} else if (p1 >= 0 && p1 < 10) k = 0; else k = -1; if (k <= 0) {_Igetc = cgetc; _Iungc = ungetc;} else {_Igetc = _Igstr; _Iungc = _Iungs;} j = 0; for (np = (&p2)[k]; *np; np++) if (*np == '%' && *(np+1) != '%' && *(np+1) != '*') ptrs[ip++] = (&p3)[(j++)+k]; return (_Iscan ((k==0 ? p1 : cin), (&p2)[k], ptrs)); } _Iscan (fileid, format, listp) char *format; int *listp; { char ch, _Inxch(); int nmatch; extern int _Isfil; _Isfil = fileid; nmatch = 0; while (1) switch (ch= *format++) { case '\0': return (nmatch); case '%': switch (_Isfrm(&format, *listp++)) { case -1: listp--; case 0: break; case -2: return (nmatch > 0 ? nmatch : -1); default: nmatch++; } case ' ': case '\n': case '\t': break; default: if (ch != _Inxch()) return(nmatch); } } int _Isfil 0; _Ichar (cptr, len) char *cptr; { char ch, _Inxch(); extern int _Isfil, (*_Igetc)(); while (len--) { if ((ch = (*_Igetc)(_Isfil)) <= 0) return (-2); if (cptr == 0) return (-1); *cptr++ = ch; } return (1); } _Iflot (fptr, length) float *fptr; int length; { char temp[75]; extern int _Inodg(), (*_Iungc)(), _Isfil; float x; int kk, ch; double atof(); if ((ch= _Inxch()) < 0) return(-2); (*_Iungc)(ch, _Isfil); if ((kk=_Isstr(temp, length, _Inodg)) <= 0) return (kk); x = atof(temp); if (fptr == 0) return (-1); *fptr = x; return (1); } _Inodg (ch) char ch; { if (_Idigt(ch,10) >= 0) return (0); switch (ch) { case 'E': case 'e': case '.': case '+': case '-': return (0); } return (1); } _Isfrm (spec, pointer) char **spec; int pointer; { int length, lflag, _Iestr(), _Ispnd(), longf; char ch; length = lflag = longf = 0; while (1) around: switch(ch = *((*spec)++)) { case '*': pointer=0; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': length = length*10 + ch - '0' ; lflag++; break; case 'o': /* octal */ return(_Iint(pointer, lflag ? length : 100, 8, longf)); case 'x': /* hex */ return(_Iint(pointer, lflag ? length : 100, 16, longf)); case 'd': /* decimal */ return (_Iint(pointer, lflag ? length : 100, 10, longf)); case 'c': /* character */ return (_Ichar(pointer, lflag ? length : 1)); case 's': /* string */ return (_Isstr(pointer, lflag ? length : 100, _Iestr)); case 'f': case 'e': /* float */ return (_Iflot(pointer, lflag ? length : 100)); case 'l': /* (long) double or int */ switch(*(*spec)) { case 'f': case 'F': case 'e': case 'E': (*spec)++; return (_Ilong (pointer, lflag ? length : 100)); case 'x': case 'X': case 'o': case 'O': case 'd': case 'D': longf=1; goto around; default: goto bad; } case '[': /* special strings */ _Imtab(spec); return (_Isstr (pointer, lflag ? length : 100, _Ispnd)); case '%': if (ch=_Inxch() != '%') return(ch < 0 ? -2 : -1); return(-1); case '\0': _Ierr("scanf: bad format termination\n"); bad: default: _Ierr ("scanf: format character %c", ch); } } ': case 'E': (*spec)++; return (_Ilong (pointer, lflag ? length : 100)); case 'x': case 'X': case 'o': case 'O': case 'd': case 'D': longf=1; goto around; default: goto bad; } case '[': /* special strings */ _Imtab(spec); return (_Isstr (pointer, lflag _Iint (iptr, length, numbase, longf) int *iptr, length; { int minus, numdig; int n, *lptr; extern int _Isfil, (*_Iungc)(), (*_Igetc)(); int c, dval; n = minus = numdig = 0; switch ((c=_Inxch())) { case '-': minus = 1; case '+': numdig++; if (_Idigt( (*_Iungc)((*_Igetc)(_Isfil),_Isfil), numbase) < 0) { (*_Iungc)(c, _Isfil); return(0); } break; case -1: /* eof */ return(-2); default: (*_Iungc)(c,_Isfil); } while ((dval=_Idigt(c=((*_Igetc)(_Isfil)), numbase ) ) >= 0 && numdig++ < length) { switch(numbase) { case 8: n = (n<<3) | dval; break; case 16: n = (n<<4) | dval; break; default: n = n*numbase + dval; } } (*_Iungc)(c,_Isfil); if (numdig == 0) return (0); if (iptr == 0) return (-1); if (minus) n = -n; if (longf) { lptr= iptr; *lptr = n; } else *iptr = n; return (1); } _Idigt (x, base) { switch (x) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': return(x-'0'); case '8': case '9': if (base > 8) return(x - '0'); case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': if (base >10) return(x - 'a' + 10); case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': if (base > 10) return(x-'A' + 10); } return(-1); } _Ilong (dptr, length) double *dptr; int length; { char temp[75]; int _Inodg(), kk; double x; double atof(); extern int (*_Iungc)(), _Isfil; extern int _Isfil, (*_Iungc)(); if ((kk = _Inxch()) < 0) return (-2); (*_Iungc)(kk,_Isfil); if ((kk = _Isstr(temp, length, _Inodg)) <= 0) return (kk); x = atof(temp); if (dptr == 0) return (-1); *dptr = x; return (1); } _Isstr (sptr, length, stopf) char *sptr; int length, (*stopf)(); { int ch, initlen, _Inxch(); extern int _Isfil, (*_Igetc)(), (*_Iungc)(), _Iestr(); initlen = length; if (stopf == _Iestr) { if ((ch=_Inxch()) < 0) return (-2); (*_Iungc)(ch,_Isfil); } while (!((*stopf)(ch=(*_Igetc)(_Isfil))) && length-- > 0) if (sptr != 0) *(sptr++) = ch; if (ch >= 0) (*_Iungc)(ch,_Isfil); if (length == initlen) return (0); if (sptr == 0) return (-1); *sptr = '\0'; return (1); } _Iestr (c) char c; { if (_Ispce(c)) return (1); if (c == '\0') return (1); return (0); } pf)(); { int ch, initlen, _Inxch(); extern int _Isfil, (*_Igetc)(), (*_Iungc)(), _Iestr(); initlen = length; if (stopf == _Iestr) { if ((ch=_Inxch()) < 0) return (-2); (*_Iungc)(ch,_Isfil); } while (!((*stopf)(ch=(*_Igetc)(_Isfil))) && length-- > 0) if (sptr != 0) *(sptr++) = ch; if (ch >= 0) (*_Iungc)(ch,_Isfil); if (length == initlen) ret_Ierr (message, a, b, c, d, e) char message[]; { extern int cgoof; printf("ERROR "); printf(message, a, b, c, d, e); cputc('\n'); cexit(cgoof); } char _Iendm[128] {0}; _Imtab (formatp) char **formatp; { /* make up special table of string ending characters */ int i, normal; char ch; /* normally all characters end string except those listed */ normal = 1; if (**formatp == '^') {normal = 0; (*formatp)++;} for (i= 0; i < 128; i++) _Iendm[i] = normal; while ((ch = *((*formatp)++)) != ']') _Iendm[ch] = !_Iendm[ch]; _Iendm[0] = 1; /* never scan past a null */ } _Inxch () /* returns next character which is not _Ispce */ { extern int _Isfil, (*_Igetc)(); int ch; while ((ch = (*_Igetc)(_Isfil)) > 0 && _Ispce(ch)); if (ch > 0) return (ch); return (-1); } _Ispce (c) char c; { switch (c) { case ' ': case '\n': case '\t': return(1); } return(0); } _Ispnd (ch) char ch; { return (_Iendm[ch] > 0); } char *_Iinpt; int (*_Igetc)(), (*_Iungc)(); _Igstr () { extern char *_Iinpt; return (*_Iinpt++); } _Iungs(ch) { extern char *_Iinpt; *--_Iinpt = ch; return(ch); } () /* returns next character which is not _Ispce */ { extern int _Isfil, (*_Igetc)(); int ch; while ((ch = (*_Igetc)(_Isfil)) > 0 && _Ispce(ch)); if (ch > 0) return (ch); return (-1); } _Ispce (c) char c; { switch (c) { case ' ': case '\n': case '\t': return(1); } return(0); } _Ispnd (ch) char ch; { return (_Iendm[ch] > 0); } char *_Iinpt; int (*_Igetc)(), (*_Iungc)(); _Igstr () { extern char *_Iinpt; return (*_Iinpt++); system(str) char *str; { int status; if(fork() == 0) execl("/bin/sh", "sh", "-c", str, 0); wait(&status); return(status); } Isfil, (*_Igetc)(); int ch; while ((ch = (*_Igetc)(_Isfil)) > 0 && _Ispce(ch)); if (ch > 0) return (ch); return (-1); } _Ispce (c) char c; { switch (c) { case ' ': case '\n': case '\t': return(1); } return(0); } _Ispnd (ch) char ch; { return (_Iendm[ch] > 0); } char *_Iinpt; int (*_Igetc)(), (*_Iungc)(); _Igstr () { extern char *_Iinpt; return (*_Iinpt++); int IEH0958g 0; tmpnam(s) char *s; { printf(-1,s,"pl%d%c",getpid(),'a'+IEH0958g++); return(s); } wait(&status); return(status); } Isfil, (*_Igetc)(); int ch; while ((ch = (*_Igetc)(_Isfil)) > 0 && _Ispce(ch)); if (ch > 0) return (ch); return (-1); } _Ispce (c) char c; { switch (c) { case ' ': case '\n': case '\t': return(1); } return(0); } _Ispnd (ch) char ch; { return (_Iendm[ch] > 0); } char *_Iinpt; int (*_Igetc)(), (*_Iungc)(); _Igstr () { extern char *_Iinpt; return (*_Iinpt++); # include "../portc1/ciodec.c" ungetc (c, fn) { struct fileps *fp; /* push back onto input */ fp = &IEH3fpts[fn]; if (fp->wrflag == 0) IEH3mbuf(fn,0); if (fp->bptr <= fp->buff - 100) IEH3err("ungetc/unprintf: buffer full file %d",fn); *--fp->bptr = c; fp->nchars++; return(c); } c; { switch (c) { case ' ': case '\n': case '\t': return(1); } return(0); } _Ispnd (ch) char ch; { return (_Iendm[ch] > 0); } char *_Iinpt; int (*_Igetc)(), (*_Iungc)(); _Igstr () { extern char *_Iinpt; return (*_Iinpt++); wdleng () /* returns number of bits in a machine integer */ /* written so kernighan can tell where he is running */ { int k, leng; k = leng = 1; while (k =<< 1) leng++; return (leng); } H3err("ungetc/unprintf: buffer full file %d",fn); *--fp->bptr = c; fp->nchars++; return(c); } c; { switch (c) { case ' ': case '\n': case '\t': return(1); } return(0); } _Ispnd (ch) char ch; { return (_Iendm[ch] > 0); } char *_Iinpt; int (*_Igetc)(), (*_Iungc)(); _Igstr () { extern char *_Iinpt; return (*_Iinpt++); : creat "agen" : note: "al.c" and "ay.c" were created from lex and yacc respectively. : The corresponding source should be found if possible. echo echo /usr/bin/agen chdir ../agen cp al.c lex.yy.c cc -O -s ay.c -ly -ll -lp mv -f a.out /usr/bin/agen rm lex.yy.c chdir /usr/bin chmod 755 agen chown bin agen : note: The source files aabin.c aahash.c aasub.c are referenced : by "agen" and must reside in "/usr/source/agen" directory. chdir /usr/source/agen ls aabin.c aahash.c aasub.c return (*_Iinpt++); : creat the unix assembler echo echo unix assembler: /bin/as /lib/as2 chdir ../as echo as1 as as1?.s ld -n -s a.out mv -f a.out /bin/as echo as2 as as2?.s ld -n -s a.out mv -f a.out /lib/as2 chmod 755 /bin/as /lib/as2 chown bin /bin/as /lib/as2 /agen rm lex.yy.c chdir /usr/bin chmod 755 agen chown bin agen : note: The source files aabin.c aahash.c aasub.c are referenced : by "agen" and must reside in "/usr/source/agen" directory. chdir /usr/source/agen ls aabin.c aahash.c aasub.c return (*_Iinpt++); : command file to creat the system library "/lib/liba.a" : $1 = {fpp | nofpp} for floating point hardware or not echo echo /lib/lib.a if $1x = x echo nofpp assumed chdir ../aslib1 echo atan.s ; as atan.s ; mv a.out ../atan.o echo atof.s ; as atof.s ; mv a.out ../atof.o echo atoi.s ; as atoi.s ; mv a.out ../atoi.o echo compar.s ; as compar.s ; mv a.out ../compar.o echo crypt.s ; as crypt.s ; mv a.out ../crypt.o echo dpadd.s ; as dpadd.s ; mv a.out ../dpadd.o echo ecvt.s ; as ecvt.s ; mv a.out ../ecvt.o echo exp.s ; as exp.s ; mv a.out ../exp.o echo floor.s ; as floor.s ; mv a.out ../floor.o echo fmod.s ; as fmod.s ; mv a.out ../fmod.o chdir ../fp if $1x != fppx goto nofpp echo fakfp.s ; as fakfp.s ; mv a.out ../fp.o goto endfp : nofpp echo fp?.s ; as fp?.s ; mv a.out ../fp.o : endfp chdir ../aslib2 echo gamma.s ; as gamma.s ; mv a.out ../gamma.o echo get.s ; as get.s ; mv a.out ../get.o echo hypot.s ; as hypot.s ; mv a.out ../hypot.o echo ldiv.s ; as ldiv.s ; mv a.out ../ldiv.o echo log.s ; as log.s ; mv a.out ../log.o echo mesg.s ; as mesg.s ; mv a.out ../mesg.o echo pow.s ; as pow.s ; mv a.out ../pow.o echo put.s ; as put.s ; mv a.out ../put.o echo qsort.s ; as qsort.s ; mv a.out ../qsort.o echo rand.s ; as rand.s ; mv a.out ../rand.o echo savr5.s ; as savr5.s ; mv a.out ../savr5.o echo sin.s ; as sin.s ; mv a.out ../sin.o echo sqrt.s ; as sqrt.s ; mv a.out ../sqrt.o echo switch.s ; as switch.s ; mv a.out ../switch.o echo lnxx.s ; as lnxx.s ; mv a.out ../lnxx.o chdir .. ar rv /lib/liba.a \ atan.o \ atof.o \ atoi.o \ crypt.o \ dpadd.o \ ecvt.o \ floor.o \ fmod.o \ fp.o \ gamma.o \ get.o \ hypot.o \ ldiv.o \ mesg.o \ pow.o \ put.o \ qsort.o \ rand.o \ savr5.o \ sin.o \ sqrt.o \ switch.o \ lnxx.o \ compar.o \ exp.o \ log.o \ rm [a-m]*.o rm *.o chmod 644 /lib/liba.a chown bin /lib/liba.a ho sin.s ; as sin.s ; mv a.out ../sin.o echo sqrt.s ; as sqrt.s ; mv a.out ../sqrt.o echo switch.s ; as switch.s ; mv a.out ../switch.o echo lnxx.s ; as lnxx.s ; mv a.out ../lnxx.o chdir .. ar rv /lib/liba.a \ atan.o \ atof.: command file to creat BASIC compiler echo echo /bin/bas chdir ../bas as bas?.s ld -s a.out -l mv -f a.out /bin/bas chmod 755 /bin/bas chown bin /bin/bas sin.o \ sqrt.o \ switch.o \ lnxx.o \ compar.o \ exp.o \ log.o \ rm [a-m]*.o rm *.o chmod 644 /lib/liba.a chown bin /lib/liba.a ho sin.s ; as sin.s ; mv a.out ../sin.o echo sqrt.s ; as sqrt.s ; mv a.out ../sqrt.o echo switch.s ; as switch.s ; mv a.out ../switch.o echo lnxx.s ; as lnxx.s ; mv a.out ../lnxx.o chdir .. ar rv /lib/liba.a \ atan.o \ atof.: This SH creates the C compiler. : $1 = {fpp, nofpp} - to designate floating hardware or not. echo echo C compiler: /lib/c0 /lib/c1 /lib/c2 if $1x = x echo nofpp assumed chdir ../cc : c0 cc -n -s -O c0*.c mv a.out c0 : cvopt cc cvopt.c mv a.out cvopt cvopt table.s table.i as table.i mv a.out table.o : c1 cc -c c1*.c if $1x = fppx cc -n -s -O c1*.o table.o if $1x != fppx cc -n -s -O -f c1*.o table.o mv a.out c1 : c2 cc -n -s -O c2*.c mv a.out c2 : Put compiler in /lib mv -f c0 /lib/c0  rm -f /lib/fc0 ln /lib/c0 /lib/fc0 mv -f c1 /lib/c1 rm -f /lib/fc1 ln /lib/c1 /lib/fc1 mv -f c2 /lib/c2 : fix permissions on compiler chdir /lib chmod 755 c0 c1 c2 fc0 fc1 chown bin c0 c1 c2 fc0 fc1 c mv a.out c0 : cvopt cc cvopt.c mv a.out cvopt cvopt table.s table.i as table.i mv a.out table.o : c1 cc -c c1*.c if $1x = fppx cc -n -s -O c1*.o table.o if $1x != fppx cc -n -s -O -f c1*.o table.o mv a.out c1 : c2 cc -n -s -O c2*.c mv a.out c2 : Put compiler in /lib mv -f c0 /lib/c0 : this command file creates the C library "/lib/libc.a" : $1 = fpp | nofpp for fpp hardware or not echo echo /lib/libc.a if $1x = x echo nofpp assumed chdir ../clib1 echo abort.s ; as abort.s ; mv a.out ../abort.o echo abs.s ; as abs.s ; mv a.out ../abs.o echo access.s; as access.s; mv a.out ../access.o echo accnt.s; as accnt.s; mv a.out ../accnt.o echo alarm.s ; as alarm.s ; mv a.out ../alarm.o echo alloc.s ; as alloc.s ; mv a.out ../alloc.o echo area.c ; cc -O -c area.c ; mv area.o ../area.o echo atof.s ; as atof.s ; mv a.out ../atof.o echo atoi.c ; cc -O -c atoi.c ; mv atoi.o ../atoi.o echo cerror.s ; as cerror.s ; mv a.out ../cerror.o echo chdir.s ; as chdir.s ; mv a.out ../chdir.o echo chmod.s ; as chmod.s ; mv a.out ../chmod.o echo chown.s ; as chown.s ; mv a.out ../chown.o echo close.s ; as close.s ; mv a.out ../close.o echo creat.s ; as creat.s ; mv a.out ../creat.o echo croot.s; as croot.s; mv a.out ../croot.o echo crt0.s ; as crt0.s ; mv -f a.out /lib/crt0.o echo csv.s ; as csv.s ; mv a.out ../csv.o echo ctime.c ; cc -O -c ctime.c ; mv ctime.o ../ctime.o chdir ../clib2 echo dup.s ; as dup.s ; mv a.out ../dup.o echo elog.s; as elog.s; mv a.out ../elog.o echo errlst.c ; cc -O -c errlst.c ; mv errlst.o ../errlst.o echo execl.s ; as execl.s ; mv a.out ../execl.o echo exect.s ; as exect.s ; mv a.out ../exect.o echo execv.s ; as execv.s ; mv a.out ../execv.o echo exit.s ; as exit.s ; mv a.out ../exit.o echo fcrt0.s ; as fcrt0.s ; mv -f a.out /lib/fcrt0.o echo ffltpr.s ; as ffltpr.s ; mv a.out ../ffltpr.o echo fltpr.s ; as fltpr.s ; mv a.out ../fltpr.o echo fork.s ; as fork.s ; mv a.out ../fork.o echo fstat.s ; as fstat.s ; mv a.out ../fstat.o chdir ../clib3 echo getc.s ; as getc.s ; mv a.out ../getc.o echo getchr.s ; as getchr.s ; mv a.out ../getchr.o echo getcsw.s ; as getcsw.s ; mv a.out ../getcsw.o echo getgid.s ; as getgid.s ; mv a.out ../getgid.o echo getpid.s ; as getpid.s ; mv a.out ../getpid.o echo getpw.c ; cc -O -c getpw.c ; mv getpw.o ../getpw.o echo getuid.s ; as getuid.s ; mv a.out ../getuid.o echo gtty.s ; as gtty.s ; mv a.out ../gtty.o echo hmul.s ; as hmul.s ; mv a.out ../hmul.o echo hsw.s ; as hsw.s ; mv a.out ../hsw.o if $1x = fppx goto fp1 echo ilongops.s ; as ilongops.s ; mv a.out ../longops.o : fp1 echo ioctl.s; as ioctl.s; mv a.out ../ioctl.o echo itol.s ; as itol.s ; mv a.out ../itol.o echo kill.s ; as kill.s ; mv a.out ../kill.o echo ladd.s ; as ladd.s ; mv a.out ../ladd.o echo lcall.s; as lcall.s; mv a.out ../lcall.o echo ldfps.s ; as ldfps.s ; mv a.out ../ldfps.o echo link.s ; as link.s ; mv a.out ../link.o echo lock.s ; as lock.s ; mv a.out ../lock.o echo locv.s ; as locv.s ; mv a.out ../locv.o if $1x != fppx goto nofp1 echo longops.s ; as longops.s ; mv a.out ../longops.o : nofp1 echo ltod.s ; as ltod.s ; mv a.out ../ltod.o echo ltoi.s ; as ltoi.s ; mv a.out ../ltoi.o chdir ../clib4 echo lseek.c ; cc -O -c lseek.c ; mv lseek.o ../lseek.o echo mcount.s ; as mcount.s ; mv a.out ../mcount.o echo mcrt0.s ; as mcrt0.s ; mv -f a.out /lib/mcrt0.o echo mknod.s ; as mknod.s ; mv a.out ../mknod.o echo mktemp.c ; cc -O -c mktemp.c ; mv mktemp.o ../mktemp.o echo mon.c ; cc -O -c mon.c ; mv mon.o ../mon.o echo mount.s ; as mount.s ; mv a.out ../mount.o echo msg.s ; as msg.s ; mv a.out ../msg.o echo nargs.s ; as nargs.s ; mv a.out ../nargs.o if $1x = fppx goto fpp echo nfrin.c ; cc -O -c nfrin.c ; mv nfrin.o ../rin.o : fpp echo nice.s ; as nice.s ; mv a.out ../nice.o echo nlist.c ; cc -O -c nlist.c ; mv nlist.o ../nlist.o echo open.s ; as open.s ; mv a.out ../open.o chdir ../clib5 echo perror.c ; cc -O -c perror.c ; mv perror.o ../perror.o echo ptrace.s; as ptrace.s; mv a.out ../ptrace.o echo pipe.s ; as pipe.s ; mv a.out ../pipe.o echo printf.s ; as printf.s ; mv a.out ../printf.o echo prof.s ; as prof.s ; mv a.out ../prof.o echo putc.s ; as putc.s ; mv a.out ../putc.o echo putchr.s ; as putchr.s ; mv a.out ../putchr.o echo qsort.c ; cc -O -c qsort.c ; mv qsort.o ../qsort.o echo read.s ; as read.s ; mv a.out ../read.o echo reset.s ; as reset.s ; mv a.out ../reset.o echo retrn.s ; as retrn.s ; mv a.out ../retrn.o if $1x != fppx goto nofpp echo rin.c ; cc -O -c rin.c ; mv rin.o ../rin.o : nofpp echo rsave.s ; as rsave.s ; mv a.out ../rsave.o chdir ../clib6 echo sbrk.s ; as sbrk.s ; mv a.out ../sbrk.o echo seek.s ; as seek.s ; mv a.out ../seek.o echo setgid.s ; as setgid.s ; mv a.out ../setgid.o echo setuid.s ; as setuid.s ; mv a.out ../setuid.o echo signal.s ; as signal.s ; mv a.out ../signal.o echo sleep.s ; as sleep.s ; mv a.out ../sleep.o echo stat.s ; as stat.s ; mv a.out ../stat.o echo stime.s ; as stime.s ; mv a.out ../stime.o echo stty.s ; as stty.s ; mv a.out ../stty.o echo sync.s ; as sync.s ; mv a.out ../sync.o chdir ../clib7 echo tell.s; as tell.s; mv a.out ../tell.o echo time.s ; as time.s ; mv a.out ../time.o echo times.s ; as times.s ; mv a.out ../times.o echo umount.s ; as umount.s ; mv a.out ../umount.o echo unlink.s ; as unlink.s ; mv a.out ../unlink.o echo vcall.s; as vcall.s; mv a.out ../vcall.o echo wait.s ; as wait.s ; mv a.out ../wait.o echo write.s ; as write.s ; mv a.out ../write.o : note: preserve the relationship fltpr.o printf.o ffltpr.o : errlst.o must follow perror.o chdir .. ar rv /lib/libc.a \ abort.o \ abs.o \ access.o \ accnt.o \ alarm.o \ alloc.o \ area.o \ atof.o \ atoi.o \ chdir.o \ chmod.o \ chown.o \ croot.o \ ctime.o \ dup.o \ elog.o \ execl.o \ fork.o \ fstat.o \ getcsw.o \ getgid.o \ getpw.o \ getuid.o \ gtty.o \ hmul.o \ ar rv /lib/libc.a \ hsw.o \ ioctl.o \ kill.o \ ladd.o \ lcall.o \ ldfps.o \ link.o \ lock.o \ locv.o \ longops.o \ ltod.o \ ltoi.o \ mcount.o \ mknod.o \ mktemp.o \ mon.o \ mount.o \ msg.o \ nice.o \ nlist.o \ itol.o \ open.o \ perror.o \ pipe.o \ ar rv /lib/libc.a \ prof.o \ ptrace.o \ putc.o \ qsort.o \ read.o \ reset.o \ retrn.o \ rin.o \ rsave.o \ sbrk.o \ setgid.o \ setuid.o \ signal.o \ sleep.o \ stat.o \ stime.o \ stty.o \ sync.o \ ar rv /lib/libc.a \ tell.o \ time.o \ times.o \ umount.o \ unlink.o \ vcall.o \ wait.o \ write.o \ creat.o \ close.o \ errlst.o \ exect.o \ execv.o \ exit.o \ fltpr.o \ printf.o \ ffltpr.o \ getc.o \ getchr.o \ getpid.o \ lseek.o \ nargs.o \ putchr.o \ seek.o \ cerror.o \ csv.o \ rm [a-m]*.o rm *.o chdir /lib chmod 644 crt0.o fcrt0.o mcrt0.o libc.a chown bin crt0.o fcrt0.o mcrt0.o libc.a \ retrn.o \ rin.o \ rsave.o \ sbrk.o \ setgid.o \ setuid.o \ signal.o \ sleep.o \ stat.o \ stime.o \ stty.o \ sync.o \ ar rv /lib/libc.a \ tell.o \ time.o \ times.o \ umount.o \ unlink.o \ vcall.o \ wait.o \ write.o \ crea: create commands in cmd1 echo echo cmd1 echo must run as super user!!! if x$1 = xfpp goto fpp if x$1 = xnofpp goto nofpp echo nofpp assumed goto noshift : nofpp if x$1 = x goto noshift shift : noshift = f -f goto aon : fpp if x$1 = x goto aon shift : aon chdir ../cmd1 if x$1 = x goto all goto $1 : all = a all : ac echo /usr/bin/ac cc -s -O ac.c mv -f a.out /usr/bin/ac chmod 755 /usr/bin/ac chown bin /usr/bin/ac if x$a = x exit : accton echo /etc/accton cc -O -s accton.c mv -f a.out /etc/accton chmod 755 /etc/accton chown bin /etc/accton if x$a = x exit : ar echo /bin/ar cc -O -s ar.c mv -f a.out /bin/ar chmod 755 /bin/ar chown bin /bin/ar if x$a = x exit : cal echo /usr/bin/cal cc -s -O cal.c mv -f a.out /usr/bin/cal chmod 755 /usr/bin/cal chown bin /usr/bin/cal if x$a = x exit : cat echo /bin/cat cc -s -O cat.c mv -f a.out /bin/cat chmod 755 /bin/cat chown bin /bin/cat if x$a = x exit : cc echo /bin/cc cc -s -n -O cc.c mv -f a.out /bin/cc chmod 755 /bin/cc chown bin /bin/cc if x$a = x exit : check echo /bin/check cc -s -O check.c mv -f a.out /bin/check chmod 755 /bin/check chown bin /bin/check if x$a = x exit : chmod echo /bin/chmod cc -O -s chmod.c mv -f a.out /bin/chmod chmod 755 /bin/chmod chown bin /bin/chmod if x$a = x exit : chown echo /bin/chown as chown.s ld -s a.out -l mv -f a.out /bin/chown chmod 755 /bin/chown chown bin /bin/chown if x$a = x exit : chroot echo /usr/bin/chroot cc -s -O chroot.c mv -f a.out /usr/bin/chroot chmod 755 /usr/bin/chroot chown bin /usr/bin/chroot if x$a = x exit : clri echo /bin/clri as clri.s strip a.out mv -f a.out /bin/clri chmod 755 /bin/clri chown bin /bin/clri if x$a = x exit : col echo /usr/bin/col cc -O -s col.c mv -f a.out /usr/bin/col chmod 755 /usr/bin/col chown bin /usr/bin/col if x$a = x exit : cmp echo /bin/cmp cc -O -s cmp.c mv -f a.out /bin/cmp chmod 755 /bin/cmp chown bin /bin/cmp if x$a = x exit : comm echo /usr/bin/comm cc -s -O comm.c mv -f a.out /usr/bin/comm chmod 755 /usr/bin/comm chown bin /usr/bin/comm if x$a = x exit : cp echo /bin/cp cc -s -O cp.c mv a.out /bin/cp1 mv -f /bin/cp1 /bin/cp chmod 755 /bin/cp chown bin /bin/cp if x$a = x exit : cpall echo /usr/bin/cpall cc -s -O cpall.c mv -f a.out /usr/bin/cpall chmod 755 /usr/bin/cpall chown bin /usr/bin/cpall if x$a = x exit : date echo /bin/date cc -O -s date.c mv -f a.out /bin/date chmod 4755 /bin/date chown root /bin/date if x$a = x exit : dcheck echo /bin/dcheck cc -s -O dcheck.c mv -f a.out /bin/dcheck chmod 755 /bin/dcheck chown bin /bin/dcheck if x$a = x exit : dd echo /bin/dd cc -s -O dd.c mv -f a.out /bin/dd chmod 755 /bin/dd chown bin /bin/dd if x$a = x exit : df echo /bin/df cc -s -O df.c mv -f a.out /bin/df chmod 755 /bin/df chown bin /bin/df if x$a = x exit : diff echo /usr/bin/diff cc -s -O diff.c mv -f a.out /usr/bin/diff chmod 755 /usr/bin/diff chown bin /usr/bin/diff if x$a = x exit : diff3 echo /usr/bin/diff3 cc -s -O diff3.c mv -f a.out /usr/lib/diff3 cp diff3.sh /usr/bin/diff3 chmod 755 /usr/bin/diff3 /usr/lib/diff3 chown bin /usr/bin/diff3 /usr/lib/diff3 if x$a = x exit : dsw echo /bin/dsw as dsw.s strip a.out mv -f a.out /bin/dsw chmod 755 /bin/dsw chown bin /bin/dsw if x$a = x exit : du echo /bin/du as du.s ld -s a.out -l mv -f a.out /bin/du chmod 755 /bin/du chown bin /bin/du if x$a = x exit : dump echo /bin/dump cc -s -O dump.c mv -f a.out /bin/dump chmod 755 /bin/dump chown bin /bin/dump if x$a = x exit cc -s -O diff3.c mv -f a.out /usr/lib/diff3 cp diff3.sh /usr/bin/diff3 chmod 755 /usr/bin/diff3 /usr/lib/diff3 chown bin /usr/bin/diff3 /usr/lib/diff3 if x$a = x exit : dsw echo: create commands in cmd2 echo echo cmd2 echo must run as super user!!! if x$1 = xfpp goto fpp if x$1 = xnofpp goto nofpp echo nofpp assumed goto noshift : nofpp if x$1 = x goto noshift shift : noshift = f -f goto aon : fpp if x$1 = x goto aon shift : aon chdir ../cmd2 if x$1 = x goto all goto $1 : all = a all : echo echo /bin/echo cc -s -O echo.c mv -f a.out /bin/echo chmod 755 /bin/echo chown bin /bin/echo if x$a = x exit : ed echo /bin/ed cc -s -n -O ed.c mv -f a.out /bin/ed chmod 755 /bin/ed chown bin /bin/ed if x$a = x exit : exit echo /bin/exit cc -s -O exit.c mv -f a.out /bin/exit chmod 755 /bin/exit chown bin /bin/exit if x$a = x exit : errdemon echo /etc/errdemon cc -O -s errdemon.c mv -f a.out /etc/errdemon chmod 755 /etc/errdemon chown bin /etc/errdemon if x$a = x exit : errpt echo /usr/bin/errpt cc -O -s errpt.c mv -f a.out /usr/bin/errpt chmod 755 /usr/bin/errpt chown bin /usr/bin/errpt if x$a = x exit : factor echo /usr/bin/factor as factor.s ld -s a.out -l mv -f a.out /usr/bin/factor chmod 755 /usr/bin/factor chown bin /usr/bin/factor if x$a = x exit : fc echo /bin/fc cc -O -s -n fc.c mv -f a.out /bin/fc chmod 755 /bin/fc chown bin /bin/fc if x$a = x exit : file echo /usr/bin/file cc -s -O file.c mv -f a.out /usr/bin/file chmod 755 /usr/bin/file chown bin /usr/bin/file if x$a = x exit : find echo /bin/find cc -s -O find.c mv -f a.out /bin/find chmod 755 /bin/find chown bin /bin/find if x$a = x exit : getty echo /etc/getty cc -s -O -n getty.c mv -f a.out /etc/getty chmod 755 /etc/getty chown bin /etc/getty if x$a = x exit : glob echo /etc/glob cc -s -O glob.c mv -f a.out /etc/glob chmod 755 /etc/glob chown bin /etc/glob if x$a = x exit : goto echo /bin/goto cc -s -O goto.c mv -f a.out /bin/goto chmod 755 /bin/goto chown bin /bin/goto if x$a = x exit : grep echo /usr/bin/grep cc -s -O grep.c mv -f a.out /usr/bin/grep chmod 755 /usr/bin/grep chown bin /usr/bin/grep if x$a = x exit : gsi echo /usr/bin/gsi cc -s -O gsi.c mv -f a.out /usr/bin/gsi chmod 755 /usr/bin/gsi chown bin /usr/bin/gsi if x$a = x exit : hyphen echo /usr/bin/hypyen cc -s -O hyphen.c mv -f a.out /usr/bin/hyphen chmod 755 /usr/bin/hyphen chown bin /usr/bin/hyphen if x$a = x exit : icheck echo /bin/icheck as ichecks.s mv a.out ichk.o cc -s -O icheck.c ichk.o rm ichk.o mv -f a.out /bin/icheck chmod 755 /bin/icheck chown bin /bin/icheck if x$a = x exit : if echo /bin/if cc -s -O if.c mv -f a.out /bin/if chmod 755 /bin/if chown bin /bin/if if x$a = x exit : init echo /etc/init cc -s -O -n init.c mv -f /etc/init /etc/oinit echo "/etc/oinit created, remove after next boot." mv -f a.out /etc/init chmod 755 /etc/init chown bin /etc/init if x$a = x exit : ino echo /bin/ino cc -s -O ino.c mv -f a.out /bin/ino chmod 755 /bin/ino chown bin /bin/ino if x$a = x exit : iostat echo /usr/bin/iostat cc -O -s iostat.c mv -f a.out /usr/bin/iostat chmod 755 /usr/bin/iostat chown bin /usr/bin/iostat if x$a = x exit : kill echo /bin/kill cc -O -s -n kill.c mv -f a.out /bin/kill chdir /etc chmod 755 getty glob init chmod 755 /bin/kill chown bin /bin/kill oinit: create commands in cmd3 echo echo cmd3 echo must run as super user!!! if x$1 = xfpp goto fpp if x$1 = xnofpp goto nofpp echo nofpp assumed goto noshift : nofpp if x$1 = x goto noshift shift : noshift = f -f goto aon : fpp if x$1 = x goto aon shift : aon chdir ../cmd3 if x$1 = x goto all goto $1 : all = a all : line echo /bin/line cc -s -O line.c mv -f a.out /bin/line chmod 755 /bin/line chown bin /bin/line if x$a = x exit : ln echo /bin/ln cc -s -O ln.c mv -f a.out /bin/ln chmod 755 /bin/ln chown bin /bin/ln if x$a = x exit : login echo /bin/login cc -s -O login.c mv -f a.out /bin/login chmod 4755 /bin/login chown root /bin/login if x$a = x exit : lpd echo /etc/lpd as lpd.s ld -s a.out -l mv -f a.out /etc/lpd chmod 4755 /etc/lpd chown root /etc/lpd if x$a = x exit : lpr echo /bin/lpr cc -s -O lpr.c mv -f a.out /bin/lpr chmod 755 /bin/lpr chown bin /bin/lpr if x$a = x exit : ls echo /bin/ls cc -s -O ls.c mv -f a.out /bin/ls chmod 755 /bin/ls chown bin /bin/ls if x$a = x exit : mail echo /usr/bin/mail cc -s -O mail.c mv -f a.out /usr/bin/mail chmod 755 /usr/bin/mail chown bin /usr/bin/mail if x$a = x exit : mesg echo /usr/bin/mesg cc -s -O mesg.c mv -f a.out /usr/bin/mesg chmod 755 /usr/bin/mesg chown bin /usr/bin/mesg if x$a = x exit : mkdir echo /bin/mkdir cc -O -s mkdir.c mv -f a.out /bin/mkdir chmod 4755 /bin/mkdir chown root /bin/mkdir if x$a = x exit : mkfs echo /etc/mkfs cc -s -O mkfs.c mv -f a.out /etc/mkfs chmod 755 /etc/mkfs chown bin /etc/mkfs if x$a = x exit : mknod echo /etc/mknod cc -s -O mknod.c mv -f a.out /etc/mknod chmod 755 /etc/mknod chown bin /etc/mknod if x$a = x exit : mkpt echo /etc/mkpt cc -s -O mkpt.c mv -f a.out /etc/mkpt chmod 755 /etc/mkpt chown bin /etc/mkpt if x$a = x exit : mount echo /etc/mount cc -s -O mount.c mv -f a.out /etc/mount chmod 755 /etc/mount chown bin /etc/mount if x$a = x exit : mtm echo /usr/bin/mtm cc -s -O mtm.c mv -f a.out /usr/bin/mtm chmod 755 /usr/bin/mtm chown bin /usr/bin/mtm if x$a = x exit : mv echo /bin/mv cc -s -O mv.c cp a.out /bin/mv rm -f a.out chmod 4755 /bin/mv chown root /bin/mv if x$a = x exit : mvall echo /usr/bin/mvall cc -s -O mvall.c mv -f a.out /usr/bin/mvall chmod 755 /usr/bin/mvall chown bin /usr/bin/mvall if x$a = x exit : ncheck echo /bin/ncheck cc -s -O ncheck.c mv -f a.out /bin/ncheck chmod 755 /bin/ncheck chown bin /bin/ncheck if x$a = x exit : nice echo /usr/bin/nice cc -s -O nice.c mv -f a.out /usr/bin/nice chmod 755 /usr/bin/nice chown bin /usr/bin/nice if x$a = x exit : nm echo /bin/nm cc -s -O nm.c mv -f a.out /bin/nm chmod 755 /bin/nm chown bin /bin/nm if x$a = x exit : nohup echo /usr/bin/nohup cc -s -O nohup.c mv -f a.out /usr/bin/nohup chmod 755 /usr/bin/nohup chown bin /usr/bin/nohup if x$a = x exit : od echo /bin/od cc -s -O od.c mv -f a.out /bin/od chmod 755 /bin/od chown bin /bin/od /bin/ncheck chown bin /bin/ncheck if x$a = x exit : nice echo /usr/bin/nice cc -s -O nice.c mv -f a.out /usr/bin/nice chmod 755 /usr/bin/nice chown bin /usr/bin/nice if x$a = x exit : nm echo /bin/nm cc -s -O nm.c mv -f a.out /bin/nm chmod 755 /b: create commands in cmd4 echo echo cmd4 echo must run as super user!!! if x$1 = xfpp goto fpp if x$1 = xnofpp goto nofpp echo nofpp assumed goto noshift : nofpp if x$1 = x goto noshift shift : noshift = f -f goto aon : fpp if x$1 = x goto aon shift : aon chdir ../cmd4 if x$1 = x goto all goto $1 : all = a all : passwd echo /usr/bin/passwd as passwd.s ld -s a.out -l mv -f a.out /usr/bin/passwd chmod 4755 /usr/bin/passwd chown root /usr/bin/passwd if x$a = x exit : pfe echo /usr/bin/pfe as pfe.s strip a.out mv -f a.out /usr/bin/pfe chmod 755 /usr/bin/pfe chown bin /usr/bin/pfe if x$a = x exit : pr echo /bin/pr cc -s -O pr.c mv -f a.out /bin/pr chmod 755 /bin/pr chown bin /bin/pr if x$a = x exit : prof echo /usr/bin/prof cc -s -O prof.c mv -f a.out /usr/bin/prof chmod 755 /usr/bin/prof chown bin /usr/bin/prof if x$a = x exit : ps echo /bin/ps cc -s -O -I/usr/source/head ps.c mv -f a.out /bin/ps chmod 755 /bin/ps chown bin /bin/ps if x$a = x exit : ptx echo /usr/bin/ptx cc -s -O ptx.c mv -f a.out /usr/bin/ptx chmod 755 /usr/bin/ptx chown bin /usr/bin/ptx if x$a = x exit : pwd echo /bin/pwd cc -s -O pwd.c mv -f a.out /bin/pwd chmod 755 /bin/pwd chown bin /bin/pwd if x$a = x exit : reloc echo /usr/bin/reloc cc -s -O reloc.c mv -f a.out /usr/bin/reloc chmod 755 /usr/bin/reloc chown bin /usr/bin/reloc if x$a = x exit : restor echo /bin/restor cc -s -O restor.c mv -f a.out /bin/restor chmod 755 /bin/restor chown bin /bin/restor if x$a = x exit : rew echo /bin/rew as rew.s strip a.out mv -f a.out /bin/rew chmod 755 /bin/rew chown bin /bin/rew if x$a = x exit : rm echo /bin/rm cc -s -O rm.c mv -f a.out /bin/rm chmod 755 /bin/rm chown bin /bin/rm if x$a = x exit : rmdir echo /bin/rmdir as rmdir.s strip a.out mv -f a.out /bin/rmdir chmod 4755 /bin/rmdir chown root /bin/rmdir in/reloc chown bin /usr/bin/reloc if x$a = x exit : restor echo /bin/restor cc -s -O restor.c mv -f a.out /bin/restor chmod 755 /bin/restor chown bin /bin/restor if x$a = x exit : rew echo /bin/rew as rew.s strip a.out mv -f a.out /bin/rew chmod 755 /b: create commands in cmd5 echo echo cmd5 echo must run as super user!!! if x$1 = xfpp goto fpp if x$1 = xnofpp goto nofpp echo nofpp assumed goto noshift : nofpp if x$1 = x goto noshift shift : noshift = f -f goto aon : fpp if x$1 = x goto aon shift : aon chdir ../cmd5 if x$1 = x goto all goto $1 : all = a all : sa echo /usr/bin/sa cc -s -O sa.c mv -f a.out /usr/bin/sa chmod 755 /usr/bin/sa chown bin /usr/bin/sa if x$a = x exit : sed echo /bin/sed cc -O -s sed0.c sed1.c mv -f a.out /bin/sed rm sed0.o sed1.o chmod 755 /bin/sed chown bin /bin/sed if x$a = x exit : sh echo /bin/sh cc -s -O -n sh.c mv -f /bin/sh /bin/osh echo "/bin/osh created, remove after next boot." mv -f a.out /bin/sh chmod 755 /bin/sh chown bin /bin/sh if x$a = x exit : size echo /bin/size cc -s -O size.c mv -f a.out /bin/size chmod 755 /bin/size chown bin /bin/size if x$a = x exit : sleep echo /usr/bin/sleep cc -s -O sleep.c mv -f a.out /usr/bin/sleep chmod 755 /usr/bin/sleep chown bin /usr/bin/sleep if x$a = x exit : sort echo /bin/sort cc -s -O sort.c mv -f a.out /bin/sort chmod 755 /bin/sort chown bin /bin/sort if x$a = x exit : split echo /usr/bin/split cc -s -O split.c mv -f a.out /usr/bin/split chmod 755 /usr/bin/split chown bin /usr/bin/split if x$a = x exit : strip echo /bin/strip as strip.s strip a.out mv -f a.out /bin/strip chmod 755 /bin/strip chown bin /bin/strip if x$a = x exit : stty echo /bin/stty cc -s -O stty.c mv -f a.out /bin/stty chmod 755 /bin/stty chown bin /bin/stty if x$a = x exit : su echo /bin/su cc -s -O su.c mv -f a.out /bin/su chmod 4755 /bin/su chown root /bin/su if x$a = x exit : sum echo /bin/sum as sum.s strip a.out mv -f a.out /bin/sum chmod 755 /bin/sum chown bin /bin/sum if x$a = x exit : sync echo /bin/sync cc -s -O sync.c mv -f a.out /bin/sync chmod 755 /bin/sync chown bin /bin/sync .out /bin/strip chmod 755 /bin/strip chown bin /bin/strip if x$a = x exit : stty echo /bin/stty cc -s -O stty.c mv -f a.out /bin/stty chmod 755 /bin/stty chown bin /bin/stty if x$a = x exit : su echo /bin/su cc -s -O su.c mv -: create commands in cmd6 echo echo cmd6 echo must run as super user!!! if x$1 = xfpp goto fpp if x$1 = xnofpp goto nofpp echo nofpp assumed goto noshift : nofpp if x$1 = x goto noshift shift : noshift = f -f goto aon : fpp if x$1 = x goto aon shift : aon chdir ../cmd6 if x$1 = x goto all goto $1 : all = a all : tail echo /usr/bin/tail cc -s -O tail.c mv -f a.out /usr/bin/tail chmod 755 /usr/bin/tail chown bin /usr/bin/tail if x$a = x exit : tee echo /usr/bin/tee cc -s -O tee.c mv -f a.out /usr/bin/tee chmod 755 /usr/bin/tee chown bin /usr/bin/tee if x$a = x exit : telinit echo /bin/telinit cc -s -O telinit.c mv -f a.out /bin/telinit chmod 744 /bin/telinit chown root /bin/telinit if x$a = x exit : time echo /bin/time cc -O -s -n time.c mv -f a.out /bin/time chmod 755 /bin/time chown bin /bin/time if x$a = x exit : tr echo /usr/bin/tr cc -s -O tr.c mv -f a.out /usr/bin/tr chmod 755 /usr/bin/tr chown bin /usr/bin/tr if x$a = x exit : typo echo /usr/bin/typo cc -s -O typo.c mv -f a.out /usr/bin/typo chmod 755 /usr/bin/typo chown bin /usr/bin/typo cp w2006 /usr/lib/w2006 chmod 644 /usr/lib/w2006 chown bin /usr/lib/w2006 if x$a = x exit : umount echo /etc/umount cc -s -O umount.c mv -f a.out /etc/umount chmod 755 /etc/umount chown bin /etc/umount if x$a = x exit : uniq echo /bin/uniq cc -s -O uniq.c mv -f a.out /bin/uniq chmod 755 /bin/uniq chown bin /bin/uniq if x$a = x exit : update echo /etc/update as update.s strip a.out mv -f a.out /etc/update chmod 755 /etc/update chown bin /etc/update if x$a = x exit : wall echo /bin/wall cc -s -O wall.c mv -f a.out /bin/wall chmod 755 /bin/wall chown bin /bin/wall if x$a = x exit : wc echo /usr/bin/wc cc -s -O wc.c mv -f a.out /usr/bin/wc chmod 755 /usr/bin/wc chown bin /usr/bin/wc if x$a = x exit : who echo /bin/who cc -s -O who.c mv -f a.out /bin/who chmod 755 /bin/who chown bin /bin/who if x$a = x exit : write echo /bin/write cc -s -O write.c mv -f a.out /bin/write chmod 755 /bin/write chown bin /bin/write od 755 /etc/update chown bin /etc/update if x$a = x exit : : creat cross reference "cref" echo echo /usr/bin/cref chdir ../cref1 echo allfuncs; cp allfuncs /usr/bin/allfuncs echo allvars; cp allvars /usr/bin/allvars echo getfcref; cp getfcref /usr/bin/getfcref echo getfuncs; cp getfuncs /usr/bin/getfuncs echo getvcref; cp getvcref /usr/bin/getvcref echo nicecref cc -O -s nicecref.c mv -f a.out /usr/bin/nicecref chdir ../cref2 echo upost cc -s -O upost.c mv -f a.out /usr/bin/upost echo crpost cc -s -O crpost.c mv -f a.out /usr/bin/crpost echo cref cc -s -O dr.c acts.c put.c mv -f a.out /usr/bin/cref cc -O -s mtab.c a.out atable atab a.out ctable ctab echo /usr/lib/atab mv -f atab /usr/lib/atab echo /usr/lib/ctab mv -f ctab /usr/lib/ctab cc -O -s make.c a.out asym aign a.out csym cign echo /usr/lib/aign mv -f aign /usr/lib/aign echo /usr/lib/cign mv -f cign /usr/lib/cign rm a.out chdir /usr/bin chmod 755 allfuncs allvars getfcref getfuncs getvcref chown bin allfuncs allvars getfcref getfuncs getvcref chmod 755 nicecref upost crpost cref chown bin nicecref upost crpost cref chdir /usr/lib chmod 644 atab ctab aign cign chown bin atab ctab aign cign ctab echo /usr/lib/atab mv -f atab /usr/lib/atab echo /usr/lib/ctab mv -f ctab /usr/lib/ctab cc -O -s make.c a.out asym aign a.out csym cign echo /usr/lib/aign mv -f aign /usr/lib/aign echo /usr/lib/cign mv -f cign /usr/lib/cign rm a.out chdir /usr/bin chmod 755 allfuncs allvars getfcref getfuncs getvcref chown bin allfuncs allvars getfcref getfuncs getvcref chmod 755 nicecref upost crpost cref chown bin nicecref upost crp: shell to recompile and install : : nroff troff suftab tmac.s tmac.scover echo echo NROFF /usr/bin/nroff /usr/lib/suftab /usr/lib/tmac.s echo /usr/lib/tmac.scover /usr/bin/troff chdir ../nroff echo t.s as t.s mv -f a.out t.o echo hytab.s as hytab.s mv -f a.out hytab.o echo nroff cc -DNROFF -n -O n[123456789].c n10.c ni.c nii.c ntab.c hytab.o t.o strip a.out mv -f a.out /usr/bin/nroff rm *.o chown bin /usr/bin/nroff chmod 755 /usr/bin/nroff echo tmac.s cp tmac.s /usr/lib/tmac.s chown bin /usr/lib/tmac.s chmod 644 /usr/lib/tmac.s echo tmac.scover cp tmac.scover /usr/lib/tmac.scover chown bin /usr/lib/tmac.scover chmod 644 /usr/lib/tmac.scover echo suftab.s as suftab.s strip a.out mv -f a.out /usr/lib/suftab chown bin /usr/lib/suftab chmod 755 /usr/lib/suftab sh ../rc/troff.rc nroff cc -DNROFF -n -O n[123456789].c n10.c ni.c nii.c ntab.c hytab.o t.o strip a.out mv -f a.out /usr/bin/nroff rm *.o chown bin /usr/bin/nroff chmod 755 /usr/bin/nroff echo tmac.s cp tmac.s /usr/lib/tmac.s chown bin /usr/lib/tma: creat "dc" and "bc" commands echo echo /bin/dc /usr/bin/bc chdir ../dc echo dc?.s ; as dc?.s ; mv -f a.out /bin/dc echo bc.c ; cc -O -s bc.c -ly ; mv -f a.out /usr/bin/bc echo lib.b ; cp lib.b /usr/lib/lib.b chmod 755 /bin/dc /usr/bin/bc chmod 644 /usr/lib/lib.b chown bin /bin/dc /usr/bin/bc /usr/lib/lib.b 9].c n10.c ni.c nii.c ntab.c hytab.o t.o strip a.out mv -f a.out /usr/bin/nroff rm *.o chown bin /usr/bin/nroff chmod 755 /usr/bin/nroff echo tmac.s cp tmac.s /usr/lib/tmac.s chown bin /usr/lib/tma: command file to creat the FORTRAN compiler echo echo FORTRAN compiler echo /bin/fc installed by cmd2.rc - not fc.rc chdir ../rc echo fc1 ; sh fc1.rc echo fc2 ; sh fc2.rc echo fc3 ; sh fc3.rc echo fc4 ; sh fc4.rc echo fcsub ; sh fcsub.rc echo fcld ; sh fcld.rc echo fciort ; sh fciort.rc echo fclib ; sh fclib.rc : fortran consists of the following: : /bin/fc fc command : /usr/fort/fc1 compiler proper : /usr/fort/f[1-4x]o.a object libraries of compiler : /usr/fort/load loads compiler from object libraries : /lib/fr0.o runtime start off : /lib/filib.a run time interpeter : /lib/libf.a standart fortran functions rc chdir ../rc echo fc1 ; sh fc1.rc echo fc2 ; sh fc2.rc echo fc3 ; sh fc3.rc echo fc4 ; sh fc4.rc echo fcsub ; sh fcsub.rc echo fcld ; sh fcld.rc echo fciort ; sh fciort.rc echo fclib ; sh fclib.rc : fortran consists of the following: : /bin/fc fc command : /usr/fort/fc1 compiler proper : /usr/fort/f[1-4x]o.a object libraries of compiler : /usr/fort/load loads compiler from object libr: create fortran "f1o.a" library echo echo /usr/fort/f1o.a chdir ../fc1 echo f11.s ; as ../fcsub/fhd.s f11.s ; mv a.out f11.o echo f12.s ; as ../fcsub/fhd.s f12.s ; mv a.out f12.o echo f13.s ; as ../fcsub/fhd.s f13.s ; mv a.out f13.o echo f14.s ; as ../fcsub/fhd.s f14.s ; mv a.out f14.o echo f15.s ; as ../fcsub/fhd.s f15.s ; mv a.out f15.o echo f16.s ; as ../fcsub/fhd.s f16.s ; mv a.out f16.o echo f17.s ; as ../fcsub/fhd.s f17.s ; mv a.out f17.o ar rv f1o.a f1?.o rm *.o mv -f f1o.a /usr/fort/f1o.a chmod 644 /usr/fort/f1o.a chown bin /usr/fort/f1o.a /fort/f1o.a chdir ../fc1 echo f11.s ; as ../fcsub/fhd.s f11.s ; mv a.out f11.o echo f12.s ; as ../fcsub/fhd.s f12.s ; mv a.out f12.o echo f13.s ; as ../fcsub/fhd.s f13.s ; mv a.out f13.o echo f14.s ; as ../fcsub/fhd.s f14.s ; mv a.out f14.o echo f15.s ; as ../fcsub/fhd.s f15.s ; mv a.out f15.o echo f16.s ; as ../fcsub/fhd.s f16.s ; mv a.out f16.o echo f17.s ; as ../fcsub/fhd.s f17.s ; mv a.out f17.o ar rv f1o.a f1?.o rm *.o mv -f f1o.a /usr/fort/f1o.a chm: command file to create fortran library "f2/f2o.a" echo echo /usr/fort/f2o.a chdir ../fc2 echo f21.s ; as ../fcsub/fhd.s f21.s ; mv a.out f21.o echo f22.s ; as ../fcsub/fhd.s f22.s ; mv a.out f22.o echo f23.s ; as ../fcsub/fhd.s f23.s ; mv a.out f23.o echo f24.s ; as ../fcsub/fhd.s f24.s ; mv a.out f24.o ar rv f2o.a f2?.o rm *.o mv -f f2o.a /usr/fort/f2o.a chmod 644 /usr/fort/f2o.a chown bin /usr/fort/f2o.a ./fcsub/fhd.s f17.s ; mv a.out f17.o ar rv f1o.a f1?.o rm *.o mv -f f1o.a /usr/fort/f1o.a chm: command file to create fortran library "f3/f3o.a" echo echo /usr/fort/f3o.a chdir ../fc3 echo f31.s ; as ../fcsub/fhd.s f31.s ; mv a.out f31.o echo f32.s ; as ../fcsub/fhd.s f32.s ; mv a.out f32.o echo f33.s ; as ../fcsub/fhd.s f33.s ; mv a.out f33.o echo f34.s ; as ../fcsub/fhd.s f34.s ; mv a.out f34.o echo f35.s ; as ../fcsub/fhd.s f35.s ; mv a.out f35.o echo f36.s ; as ../fcsub/fhd.s f36.s ; mv a.out f36.o echo f37.s ; as ../fcsub/fhd.s f37.s ; mv a.out f37.o echo f38.s ; as ../fcsub/fhd.s f38.s ; mv a.out f38.o echo f39.s ; as ../fcsub/fhd.s f39.s ; mv a.out f39.o ar rv f3o.a f3?.o ar mav f39.o f3o.a f32.o rm *.o mv -f f3o.a /usr/fort/f3o.a chmod 644 /usr/fort/f3o.a chown bin /usr/fort/f3o.a o echo f33.s ; as ../fcsub/fhd.s f33.s ; mv a.out f33.o echo f34.s ; as ../fcsub/fhd.s f34.s ; mv a.out f34.o echo f35.s ; as ../fcsub/fhd.s f35.s ; mv a.out f35.o echo f36.s ; as ../fcsub/fhd.s f36.s ; mv a.out f36.o echo f37.s ; as ../fcsub/fhd.s f37.s ; mv a.out f37.o echo f38.s ; as ../fcsub/fhd.s f38.s ; m: command file to create fortran library "f4/f4o.a" echo echo /usr/fort/f4o.a chdir ../fc4 echo f41.s ; as ../fcsub/fhd.s f41.s ; mv a.out f41.o echo f42.s ; as ../fcsub/fhd.s f42.s ; mv a.out f42.o echo f43.s ; as ../fcsub/fhd.s f43.s ; mv a.out f43.o echo f44.s ; as ../fcsub/fhd.s f44.s ; mv a.out f44.o echo f45.s ; as ../fcsub/fhd.s f45.s ; mv a.out f45.o echo f46.s ; as ../fcsub/fhd.s f46.s ; mv a.out f46.o echo f47.s ; as ../fcsub/fhd.s f47.s ; mv a.out f47.o ar rv f4o.a f4?.o rm *.o mv -f f4o.a /usr/fort/f4o.a chmod 644 /usr/fort/f4o.a chown bin /usr/fort/f4o.a /fort/f4o.a chdir ../fc4 echo f41.s ; as ../fcsub/fhd.s f41.s ; mv a.out f41.o echo f42.s ; as ../fcsub/fhd.s f42.s ; mv a.out f42.o echo f43.s ; as ../fcsub/fhd.s f43.s ; mv a.out f43.o echo f44.s ; as ../fcsub/fhd.s f44.s ; mv a.out f44.o echo f45.s ; as ../fcsub/fhd.s f45.s ; mv a.out f45.o echo f46.s ; as ../fcsub/fhd.s f46.s ; mv a.out f46.o echo f47.s ; as ../fcsub/fhd.s f47.s ; mv a.out f47.o ar rv f4o.a f4?.o rm *.o mv -f f4o.a /: command file to creat fortran library "filib.a" echo echo /lib/filib.a /lib/fr0.o chdir ../fcio echo io?.s ; as io?.s ; mv a.out ../io.o chdir ../fcrt echo r0.s ; as r0.s ; mv -f a.out /lib/fr0.o echo r1.s ; as r1.s ; mv a.out ../r1.o echo r2.s ; as r2.s ; mv a.out ../r2.o echo r3.s ; as r3.s ; mv a.out ../r3.o echo r4.s ; as r4.s ; mv a.out ../r4.o echo r5.s ; as r5.s ; mv a.out ../r5.o echo r6.s ; as r6.s ; mv a.out ../r6.o echo r7.s ; as r7.s ; mv a.out ../r7.o echo r8.s ; as r8.s ; mv a.out ../r8.o echo r9.s ; as r9.s ; mv a.out ../r9.o echo ra.s ; as ra.s ; mv a.out ../ra.o echo rb.s ; as rb.s ; mv a.out ../rb.o echo rc.s ; as rc.s ; mv a.out ../rc.o echo rd.s ; as rd.s ; mv a.out ../rd.o echo re.s ; as re.s ; mv a.out ../re.o echo rf.s ; as rf.s ; mv a.out ../rf.o echo rg.s ; as rg.s ; mv a.out ../rg.o echo rh.s ; as rh.s ; mv a.out ../rh.o echo rx.s ; as rx.s ; mv a.out ../rx.o chdir .. ar rv filib.a io.o r?.o rm *.o mv -f filib.a /lib/filib.a chmod 644 /lib/fr0.o /lib/filib.a chown bin /lib/fr0.o /lib/filib.a r9.s ; mv a.out ../r9.o echo ra.s ; as ra.s ; mv a.out ../ra.o echo rb.s ; as rb.s ; mv a.out ../rb.o echo rc.s ; as rc.s ; mv a.out ../rc.o echo rd.s ; as rd.s ; mv a.out ../rd.o echo re.s ; as re.s ; mv a.out ../re.o echo rf.s ; as rf.s ; mv a.out ../rf.o echo rg.s ; as rg.s ; mv a.out ../rg.o echo rh.s ; as rh.s ; mv a.out ../rh.o echo rx.s ; as rx.s ; mv a.out ../rx.o chdir .. ar rv filib.a io.o r?.o rm *.o mv -f filib.a /lib/filib.a chmod 644 /lib/fr0.o /lib/filib.a chown bin /lib/fr: command file to load fortran compiler echo echo /usr/fort/load /usr/fort/fc1 chdir /usr/fort ed - a ld -u pass1 -u pass2 -u pass3 -u pass4 \ f1o.a f2o.a f3o.a f4o.a fxo.a -l . w load q sh load strip a.out echo fc1 ; mv -f a.out fc1 chmod 755 fc1 load chown bin fc1 load ho rg.s ; as rg.s ; mv a.out ../rg.o echo rh.s ; as rh.s ; mv a.out ../rh.o echo rx.s ; as rx.s ; mv a.out ../rx.o chdir .. ar rv filib.a io.o r?.o rm *.o mv -f filib.a /lib/filib.a chmod 644 /lib/fr0.o /lib/filib.a chown bin /lib/fr: command file to creat fortran library /lib/libf.a echo echo /usr/fort/errors /lib/libf.a chdir ../fclib1 echo abs.s ; as abs.s ; mv a.out ../abs.o echo aimag.s ; as aimag.s ; mv a.out ../aimag.o echo aint.s ; as aint.s ; mv a.out ../aint.o echo alog.s ; as alog.s ; mv a.out ../alog.o echo alog10.s ; as alog10.s ; mv a.out ../alog10.o echo amax0.s ; as amax0.s ; mv a.out ../amax0.o echo amax1.s ; as amax1.s ; mv a.out ../amax1.o echo amin0.s ; as amin0.s ; mv a.out ../amin0.o echo amin1.s ; as amin1.s ; mv a.out ../amin1.o echo amod.s ; as amod.s ; mv a.out ../amod.o echo atan.s ; as atan.s ; mv a.out ../atan.o echo atan2.s ; as atan2.s ; mv a.out ../atan2.o chdir ../fclib2 echo cabs.s ; as cabs.s ; mv a.out ../cabs.o echo ccos.f ; fc -c ccos.f ; mv ccos.o ../ccos.o echo cexp.f ; fc -c cexp.f ; mv cexp.o ../cexp.o echo clog.f ; fc -c clog.f ; mv clog.o ../clog.o echo cmplx.s ; as cmplx.s ; mv a.out ../cmplx.o echo conjg.s ; as conjg.s ; mv a.out ../conjg.o echo cos.s ; as cos.s ; mv a.out ../cos.o echo csin.f ; fc -c csin.f ; mv csin.o ../csin.o echo csqrt.f ; fc -c csqrt.f ; mv csqrt.o ../csqrt.o echo dble.s ; as dble.s ; mv a.out ../dble.o echo dccos.f ; fc -c dccos.f ; mv dccos.o ../dccos.o echo dcexp.f ; fc -c dcexp.f ; mv dcexp.o ../dcexp.o echo dclog.f ; fc -c dclog.f ; mv dclog.o ../dclog.o echo dcsin.f ; fc -c dcsin.f ; mv dcsin.o ../dcsin.o echo dcsqrt.f ; fc -c dcsqrt.f; mv dcsqrt.o ../dcsqrt.o echo dim.s ; as dim.s ; mv a.out ../dim.o echo dimag.s ; as dimag.s ; mv a.out ../dimag.o echo exp.s ; as exp.s ; mv a.out ../exp.o chdir ../fclib3 echo float.s ; as float.s ; mv a.out ../float.o echo iabs.s ; as iabs.s ; mv a.out ../iabs.o echo idim.s ; as idim.s ; mv a.out ../idim.o echo idint.s ; as idint.s ; mv a.out ../idint.o echo ierr.s ; as ierr.s ; mv a.out ../ierr.o echo ifix.s ; as ifix.s ; mv a.out ../ifix.o echo isign.s ; as isign.s ; mv a.out ../isign.o echo mod.s ; as mod.s ; mv a.out ../mod.o echo real.s ; as real.s ; mv a.out ../real.o echo sign.s ; as sign.s ; mv a.out ../sign.o echo sin.s ; as sin.s ; mv a.out ../sin.o echo sngl.s ; as sngl.s ; mv a.out ../sngl.o echo sqrt.s ; as sqrt.s ; mv a.out ../sqrt.o echo tanh.f ; fc -c tanh.f ; mv tanh.o ../tanh.o chdir ../fclib4 echo ctime.s ; as ctime.s ; mv a.out ../ctime.o echo errors ; cp errors /usr/fort/errors echo getarg.s ; as getarg.s ; mv a.out ../getarg.o echo nice.s ; as nice.s ; mv a.out ../nice.o : echo openrw.s ; as openrw.s ; mv a.out ../openrw.o echo orand.s ; as orand.s ; mv a.out ../orand.o echo plot.s ; as plot.s ; mv a.out ../plot.o echo rand.s ; as rand.s ; mv a.out ../rand.o echo rio.s ; as rio.s ; mv a.out ../rio.o echo setfil.s ; as setfil.s ; mv a.out ../setfil.o echo sleep.s ; as sleep.s ; mv a.out ../sleep.o echo uio.s ; as uio.s ; mv a.out ../uio.o chdir .. ar rv libf.a \ abs.o \ aimag.o \ aint.o \ alog10.o \ amax0.o \ amax1.o \ amin0.o \ amin1.o \ amod.o \ atan.o \ ccos.o \ cexp.o \ clog.o \ cmplx.o \ conjg.o \ csin.o \ csqrt.o \ ctime.o \ dble.o \ dccos.o \ dcexp.o \ dclog.o \ dcsin.o \ dcsqrt.o \ dim.o \ dimag.o \  ar rv libf.a \ float.o \ getarg.o \ iabs.o \ idim.o \ idint.o \ ierr.o \ ifix.o \ isign.o \ mod.o \ nice.o \ rand.o \ real.o \ setfil.o \ sign.o \ sleep.o \ sngl.o \ tanh.o \ uio.o \ alog.o \ atan2.o \ cabs.o \ cos.o \ exp.o \ sin.o \ sqrt.o \ orand.o \ plot.o \ rio.o \ rm [a-m]*.o rm *.o mv -f libf.a /lib/libf.a chmod 644 /lib/libf.a /usr/fort/errors chown bin /lib/libf.a /usr/fort/errors onjg.o \ csin.o \ csqrt.o \ ctime.o \ dble.o \ dccos.o \ dcexp.o \ dclog.o \ dcsin.o \ dcsqrt.o \ dim.o \ dimag.o \ : command file to create fortran library "fx/fxo.a" echo echo /usr/fort/fxo.a chdir ../fcsub echo fx1.s ; as fhd.s fx1.s ; mv a.out fx1.o echo fx2.s ; as fhd.s fx2.s ; mv a.out fx2.o echo fx3.s ; as fhd.s fx3.s ; mv a.out fx3.o echo fx4.s ; as fhd.s fx4.s ; mv a.out fx4.o echo fx5.s ; as fhd.s fx5.s ; mv a.out fx5.o echo fx6.s ; as fhd.s fx6.s ; mv a.out fx6.o echo fx7.s ; as fhd.s fx7.s ; mv a.out fx7.o echo fx8.s ; as fhd.s fx8.s ; mv a.out fx8.o echo fx9.s ; as fhd.s fx9.s ; mv a.out fx9.o echo fxa.s ; as fhd.s fxa.s ; mv a.out fxa.o echo fxb.s ; as fhd.s fxb.s ; mv a.out fxb.o echo fxc.s ; as fhd.s fxc.s ; mv a.out fxc.o echo fxd.s ; as fhd.s fxd.s ; mv a.out fxd.o echo fxe.s ; as fhd.s fxe.s ; mv a.out fxe.o echo fxf.s ; as fhd.s fxf.s ; mv a.out fxf.o echo fxg.s ; as fhd.s fxg.s ; mv a.out fxg.o echo fxh.s ; as fhd.s fxh.s ; mv a.out fxh.o echo fxi.s ; as fhd.s fxi.s ; mv a.out fxi.o echo fxx.s ; as fhd.s fxx.s ; mv a.out fxx.o ar rv fxo.a fx?.o rm *.o mv -f fxo.a /usr/fort/fxo.a chmod 644 /usr/fort/fxo.a chown bin /usr/fort/fxo.a echo fxb.s ; as fhd.s fxb.s ; mv a.out fxb.o echo fxc.s ; as fhd.s fxc.s ; mv a.out fxc.o echo fxd.s ; as fhd.s fxd.s ; mv a.out fxd.o echo fxe.s ; as fhd.s fxe.s ; mv a.out fxe.o echo fxf.s ; as fhd.s fxf.s ; mv a.out fxf.o echo fxg.s ; as fhd.s fxg.s ; mv a.out fxg.o echo fxh.s ; as fhd.s fxh.s ; mv a.out fxh.o echo fxi.s ; as fhd.s fxi.s ; mv a.out fxi.o echo fxx.s ; as fhd.s fxx.s ; mv a.out fxx.o ar rv fxo.a fx?.o rm *.o mv -f fxo.a /usr/fort/fxo.a chmod 644 /usr/for: creat "fed" command echo echo /usr/bin/fed chdir ../fed echo fed?.s ; as fed?.s ../form/form[56].s strip a.out mv -f a.out /usr/bin/fed chmod 755 /usr/bin/fed chown bin /usr/bin/fed hd.s fxe.s ; mv a.out fxe.o echo fxf.s ; as fhd.s fxf.s ; mv a.out fxf.o echo fxg.s ; as fhd.s fxg.s ; mv a.out fxg.o echo fxh.s ; as fhd.s fxh.s ; mv a.out fxh.o echo fxi.s ; as fhd.s fxi.s ; mv a.out fxi.o echo fxx.s ; as fhd.s fxx.s ; mv a.out fxx.o ar rv fxo.a fx?.o rm *.o mv -f fxo.a /usr/fort/fxo.a chmod 644 /usr/for: creat "form" command echo echo /usr/bin/form chdir ../form echo form?.s ; as form?.s strip a.out mv -f a.out /usr/bin/form chmod 755 /usr/bin/form chown bin /usr/bin/form sr/bin/fed hd.s fxe.s ; mv a.out fxe.o echo fxf.s ; as fhd.s fxf.s ; mv a.out fxf.o echo fxg.s ; as fhd.s fxg.s ; mv a.out fxg.o echo fxh.s ; as fhd.s fxh.s ; mv a.out fxh.o echo fxi.s ; as fhd.s fxi.s ; mv a.out fxi.o echo fxx.s ; as fhd.s fxx.s ; mv a.out fxx.o ar rv fxo.a fx?.o rm *.o mv -f fxo.a /usr/fort/fxo.a chmod 644 /usr/for: creat the UNIX io driver library "/usr/sys/lib2" : must be called with 40, 45 or 70 argument echo echo /usr/sys/lib2 if $1x != 40x -a $1x != 45x -a $1x != 70x \ sh -c 'echo An argument of 40, 45 or 70 is expected; exit ' chdir ../io1 echo bio.c; cc -c -O bio.c; mv -f bio.o ../io2/bio.o echo cm.c; cc -c -O cm.c; mv -f cm.o ../io2/cm.o echo dc.c; cc -c -O dc.c; mv -f dc.o ../io2/dc.o echo dh.c; cc -c -O dh.c; mv -f dh.o ../io2/dh.o echo dhdm.c; cc -c -O dhdm.c; mv -f dhdm.o ../io2/dhdm.o echo dhfdm.c; cc -c -O dhfdm.c; mv -f dhfdm.o ../io2/dhfdm.o echo dn.c; cc -c -O dn.c; mv -f dn.o ../io2/dn.o echo dp.c; cc -c -O dp.c; mv -f dp.o ../io2/dp.o echo hd.c; cc -c -O hd.c; mv -f hd.o ../io2/hd.o echo hp.c; cc -c -O hp.c; mv -f hp.o ../io2/hp.o echo hs.c; cc -c -O hs.c; mv -f hs.o ../io2/hs.o echo ht.c; cc -c -O ht.c; mv -f ht.o ../io2/ht.o echo kl.c; cc -c -O kl.c; mv -f kl.o ../io2/kl.o echo lp.c; cc -c -O lp.c; mv -f lp.o ../io2/lp.o chdir ../io2 echo malloc.c; cc -O -c malloc.c; echo mem.c; cc -O -c mem.c; echo partab.c; cc -O -c partab.c; echo pc.c; cc -O -c pc.c; echo pipe.c; cc -O -c pipe.c; echo rf.c; cc -O -c rf.c; echo rh.c; cc -O -c rh.c; echo rk.c; cc -O -c rk.c; echo rp.c; cc -O -c rp.c; echo sys.c; cc -O -c sys.c; echo tc.c; cc -O -c tc.c; echo tm.c; cc -O -c tm.c; echo tty.c; cc -O -c tty.c; : note: preserve the relationship dhdm.o dh.o dhfdm.o ar rv /usr/sys/lib2 \ bio.o \ tty.o \ malloc.o \ pipe.o \ cm.o\ dc.o \ dn.o \ dp.o \ hd.o\ kl.o \ mem.o \ pc.o \ rf.o \ rh.o \ rk.o \ tc.o \ tm.o \ partab.o \ rp.o \ lp.o \ dhdm.o \ dh.o \ dhfdm.o \ hp.o \ ht.o \ hs.o\ sys.o rm *.o chmod 644 /usr/sys/lib2 chown bin /usr/sys/lib2 if $1x != 40x exit echo lib40 insert for 11/40 echo rhf.c; cc -O -c rhf.c ar rv /usr/sys/lib40 rhf.o rm rhf.o exit tc.c; echo tm.c; cc -O -c tm.c; echo tty.c; cc -O -c tty.c; : note: preserve the relationship dhdm.o dh.o dhfdm.o ar rv /usr/sys/lib2 \ bio.o \ tty.o \ malloc.o \ pipe.o \ cm.o\ dc.o \ dn.o \ dp.o \ hd.o\ kl.o \ mem.o \ pc.o \ rf.o \ rh.o \ rk.o \ tc.o \ tm.o \ partab.: creat the linkage editor "ld" echo echo /bin/ld /usr/sys/sysfix chdir ../ld echo ld.c ; cc -O -s -n ld.c ; mv -f a.out /bin/ld echo sysfix.c ; cc -O -s sysfix.c ; mv -f a.out /usr/sys/sysfix chmod 755 /bin/ld /usr/sys/sysfix chown bin /bin/ld /usr/sys/sysfix -c tm.c; echo tty.c; cc -O -c tty.c; : note: preserve the relationship dhdm.o dh.o dhfdm.o ar rv /usr/sys/lib2 \ bio.o \ tty.o \ malloc.o \ pipe.o \ cm.o\ dc.o \ dn.o \ dp.o \ hd.o\ kl.o \ mem.o \ pc.o \ rf.o \ rh.o \ rk.o \ tc.o \ tm.o \ partab.: creat lexical analysis program generator "lex" echo echo /lib/libl.a /lib/liblc.a /usr/bin/lex chdir ../lexcl echo input.c; cc -c -O input.c echo output.c; cc -c -O output.c echo unput.c; cc -c -O unput.c echo main.c; cc -c -O main.c echo yymore.c; cc -c -O yymore.c echo yywrap.c; cc -c -O yywrap.c echo yyless.c; cc -c -O yyless.c echo reject.c; cc -c -O reject.c ar rv /lib/libl.a input.o output.o unput.o main.o yymore.o yywrap.o yyless.o \ reject.o rm /lib/liblc.a ln /lib/libl.a /lib/liblc.a rm *.o chdir ../lexgen1 echo lgen.c; cc -c -O lgen.c; mv lgen.o ../lexgen2/lgen.o echo defrd.c; cc -c -O defrd.c; mv defrd.o ../lexgen2/defrd.o echo cform.c; cc -c -O cform.c; mv cform.o ../lexgen2/cform.o echo cpyact.c; cc -c -O cpyact.c; mv cpyact.o ../lexgen2/cpyact.o echo access.c; cc -c -O access.c; mv access.o ../lexgen2/access.o echo auto.c; cc -c -O auto.c; mv auto.o ../lexgen2/auto.o echo errio.c; cc -c -O errio.c; mv errio.o ../lexgen2/errio.o echo lam.c; cc -c -O lam.c; mv lam.o ../lexgen2/lam.o echo defst.c; cc -c -O defst.c; mv defst.o ../lexgen2/defst.o echo anoth.c; cc -c -O anoth.c; mv anoth.o ../lexgen2/anoth.o echo chset.c; cc -c -O chset.c; mv chset.o ../lexgen2/chset.o echo common.c; cc -c -O common.c; mv common.o ../lexgen2/common.o echo ctrans.c; cc -c -O ctrans.c; mv ctrans.o ../lexgen2/ctrans.o echo header.c; cc -c -O header.c; mv header.o ../lexgen2/header.o echo extdef.c; cc -c -O extdef.c; mv extdef.o ../lexgen2/extdef.o echo csubs.c; cc -c -O csubs.c; mv csubs.o ../lexgen2/csubs.o chdir ../lexgen2 echo rdrule.c; cc -c -O rdrule.c echo nofree.c; cc -c -O nofree.c echo subset.c; cc -c -O subset.c echo tail.c; cc -c -O tail.c echo purge.c; cc -c -O purge.c echo outstp.c; cc -c -O outstp.c echo ssort.c; cc -c -O ssort.c echo rdcomm.c; cc -c -O rdcomm.c echo move.c; cc -c -O move.c echo start.c; cc -c -O start.c echo rprint.c; cc -c -O rprint.c echo range.c; cc -c -O range.c echo usrtab.c; cc -c -O usrtab.c echo setflg.c; cc -c -O setflg.c ar rv lex.a lgen.o defrd.o rdrule.o nofree.o subset.o tail.o \ purge.o cform.o outstp.o cpyact.o ssort.o access.o rdcomm.o \ auto.o move.o errio.o lam.o start.o defst.o anoth.o rprint.o range.o \ usrtab.o chset.o common.o ctrans.o setflg.o header.o extdef.o csubs.o rm -f *.o cc -O -s lex.a -lp mv -f a.out /usr/bin/lex rm lex.a chmod 644 /lib/libl.a chmod 755 /usr/bin/lex chown bin /usr/bin/lex /lib/libl.a t.c echo range.c; cc -c -O range.c echo usrtab.c; cc -c -O usrtab.c echo setflg.c; cc -c -O setflg.c ar rv lex.a lgen.o defrd.o rdrule.o nofree.o subset.o tai: creat the "lil" compiler : lil consists of: : /usr/bin/lc lc command : /usr/lib/lil1 lil compiler pass 1 : /usr/lib/lil2 lil compiler pass 2 echo echo LIL compiler chdir ../lil echo /usr/bin/lc ; cc -O -s lc.c ; mv -f a.out /usr/bin/lc echo grammar ; yacc grammar : note: expect 3 shift/reduce conflicts ed - y.tab.c g/#/d 1;/yyactr/-1d /nterms/-1,$d w tables q echo /usr/lib/lil1 ; cc -O -s ???.c ; mv -f a.out /usr/lib/lil1 echo /usr/lib/lil2 ; cc -O -s pass2c.c ; mv -f a.out /usr/lib/lil2 rm y.tab.c *.o tables chdir /usr/lib chmod 755 lil1 lil2 /usr/bin/lc chown bin lil1 lil2 /usr/bin/lc compiler pass 1 : /usr/lib/lil2 lil compiler pass 2 echo echo LIL compiler chdir ../lil echo /usr/bin/lc ; cc -O -s lc.c ; mv -f a.out /usr/bin/lc echo grammar ; yacc grammar : note: expect 3 shift/reduce conflicts ed - y.tab.c g/#/d 1;/yyactr/-1d /nterms/-1,$d w tables q echo /usr/lib/lil1 ; cc -O -s ???.c ; mv -f a.out /usr/lib/lil1 echo /usr/lib/lil2 ; cc -O -s pass2c.c ; mv -f a.out /usr/lib/lil2 rm y.ta: shell to recompile and install /usr/bin/neqn echo echo /usr/bin/neqn echo This runcom depends on yacc to work. chdir ../neqn echo neqn yacc ne.g cc -O -n ne*.c -ly rm *.o rm y.tab.c mv -f a.out /usr/bin/neqn chown bin /usr/bin/neqn chmod 755 /usr/bin/neqn sh ../rc/eqn.rc note: expect 3 shift/reduce conflicts ed - y.tab.c g/#/d 1;/yyactr/-1d /nterms/-1,$d w tables q echo /usr/lib/lil1 ; cc -O -s ???.c ; mv -f a.out /usr/lib/lil1 echo /usr/lib/lil2 ; cc -O -s pass2c.c ; mv -f a.out /usr/lib/lil2 rm y.ta: shell to recompile and install /usr/bin/troff echo echo /usr/bin/troff chdir ../nroff echo t.s as t.s mv -f a.out t.o echo hytab.s as hytab.s mv -f a.out hytab.o echo troff cc -n -O n[12345789].c t6.c t10.c ni.c nii.c tab3.c hytab.o t.o strip a.out mv -f a.out /usr/bin/troff rm *.o chown bin /usr/bin/troff chmod 755 /usr/bin/troff yyactr/-1d /nterms/-1,$d w tables q echo /usr/lib/lil1 ; cc -O -s ???.c ; mv -f a.out /usr/lib/lil1 echo /usr/lib/lil2 ; cc -O -s pass2c.c ; mv -f a.out /usr/lib/lil2 rm y.ta: creat the UNIX os library "/usr/sys/lib1" : must be called with argument 70, 45 or 40 echo echo /usr/sys/lib1 if $1x != 40x -a $1x != 45x -a $1x != 70x \ sh -c "echo An argument of 40, 45, or 70 is expected; exit" chdir ../opsys echo acct.c; cc -c -O acct.c echo alloc.c; cc -c -O alloc.c echo clock.c; cc -c -O clock.c echo errlog.c; cc -c -O errlog.c echo fio.c; cc -c -O fio.c echo iget.c; cc -c -O iget.c echo main.c; cc -c -O main.c echo messag.c; cc -c -O messag.c echo nami.c; cc -c -O nami.c echo prf.c; cc -c -O prf.c echo rdwri.c; cc -c -O rdwri.c echo sig.c; cc -c -O sig.c echo slp.c; cc -c -O slp.c echo subr.c; cc -c -O subr.c echo sys1.c; cc -c -O sys1.c echo sys2.c; cc -c -O sys2.c echo sys3.c; cc -c -O sys3.c echo sys4.c; cc -c -O sys4.c echo sys5.c; cc -c -O sys5.c echo sysent.c; cc -c -O sysent.c echo text.c; cc -c -O text.c echo trap.c; cc -c -O trap.c ar rv /usr/sys/lib1 \ main.o \ alloc.o \ iget.o \ prf.o \ rdwri.o \ slp.o \ subr.o \ text.o \ trap.o \ sig.o \ sysent.o \ sys1.o \ sys2.o \ sys3.o \ sys4.o \ sys5.o \ nami.o \ fio.o \ messag.o \ clock.o\ acct.o\ errlog.o rm *.o chmod 644 /usr/sys/lib1 chown bin /usr/sys/lib1 if $1x != 40x exit echo lib40 insert for 11/40 system echo messagf.c; cc -c -O messagf.c echo errlogf.c; cc -c -O errlogf.c echo sysf.c; cc -c -O sys5f.c ar rv /usr/sys/lib40 messagf.o sys5f.o errlogf.o rm messagf.o sys5f.o errlogf.o exit /usr/sys/lib1 \ main.o \ alloc.o \ iget.o \ prf.o \ rdwri.o \ slp.o \ subr.o \ text.o \ trap.o \ sig.o \ sysent.o \ sys1.o \ sys2.o \ : creat portable C library "libp.a" echo echo /lib/libp.a chdir ../portc1 echo calloc.c; cc -c -O calloc.c; mv calloc.o ../portc2/calloc.o echo cclose.c; cc -c -O cclose.c; mv cclose.o ../portc2/cclose.o echo ceof.c; cc -c -O ceof.c; mv ceof.o ../portc2/ceof.o echo cerr2.c; cc -c -O cerr2.c; mv cerr2.o ../portc2/cerr2.o echo cerror.c; cc -c -O cerror.c; mv cerror.o ../portc2/cerror.o echo cexit.c; cc -c -O cexit.c; mv cexit.o ../portc2/cexit.o echo cflush.c; cc -c -O cflush.c; mv cflush.o ../portc2/cflush.o echo cfree.c; cc -c -O cfree.c; mv cfree.o ../portc2/cfree.o echo cgetc.c; cc -c -O cgetc.c; mv cgetc.o ../portc2/cgetc.o echo ciodec.c; cc -c -O ciodec.c; mv ciodec.o ../portc2/ciodec.o echo clenf.c; cc -c -O clenf.c; mv clenf.o ../portc2/clenf.o echo copen.c; cc -c -O copen.c; mv copen.o ../portc2/copen.o echo cputc.c; cc -c -O cputc.c; mv cputc.o ../portc2/cputc.o echo cwrd.c; cc -c -O cwrd.c; mv cwrd.o ../portc2/cwrd.o echo exit.c; cc -c -O exit.c; mv exit.o ../portc2/exit.o echo ftoa.c; cc -c -O ftoa.c; mv ftoa.o ../portc2/ftoa.o echo getch.c; cc -c -O getch.c; mv getch.o ../portc2/getch.o echo gets.c; cc -c -O gets.c; mv gets.o ../portc2/gets.o echo getvec.c; cc -c -O getvec.c; mv getvec.o ../portc2/getvec.o chdir ../portc2 echo ihexit.s; as ihexit.s; mv a.out IHexit.o echo intss.c; cc -c -O intss.c echo makbuf.c; cc -c -O makbuf.c echo maktab.c; cc -c -O maktab.c echo portlb.c; cc -c -O portlb.c echo printf.c; cc -c -O printf.c echo putch.c; cc -c -O putch.c echo puts.c; cc -c -O puts.c echo relvec.c; cc -c -O relvec.c echo rew.c; cc -c -O rew.c echo scan1.c; cc -c -O scan1.c echo scan2.c; cc -c -O scan2.c echo scan3.c; cc -c -O scan3.c echo system.c; cc -c -O system.c echo tmpnam.c; cc -c -O tmpnam.c echo unget.c; cc -c -O unget.c echo wdleng.c; cc -c -O wdleng.c ar rv /lib/libp.a tmpnam.o printf.o ftoa.o clenf.o scan1.o scan2.o \ scan3.o gets.o puts.o cwrd.o maktab.o unget.o getch.o cgetc.o putch.o \ cerror.o copen.o cputc.o makbuf.o rew.o cflush.o ceof.o cerr2.o cexit.o \ cclose.o getvec.o relvec.o wdleng.o system.o ciodec.o calloc.o cfree.o \ intss.o exit.o portlb.o IHexit.o chmod 644 /lib/libp.a chown bin /lib/libp.a rm *.o scan3.c echo system.c; cc -c -O system.c echo tmpnam.c; cc -c -O tmpnam.c echo unget.c; cc -c -O unget.c echo wdleng.c; cc -c -O wdleng.c ar rv /lib/libp.a tmpnam.o printf.o ftoa.o clenf.o scan1.o scan2.o \ scan3.o gets.o puts.o cwrd.o maktab.o unget.o getch.o cgetc.o putch.o \ cerror.o copen.o cputc.o makbuf.o rew.o cflush.o ceof.o cerr2.o cexit.o \ cclose.o getvec.o relvec: creat SNOBOL interpeter "sno" echo echo /usr/bin/sno chdir ../sno cc -O -n -s sno?.c mv -f a.out /usr/bin/sno rm *.o chmod 755 /usr/bin/sno chown bin /usr/bin/sno stem.c echo tmpnam.c; cc -c -O tmpnam.c echo unget.c; cc -c -O unget.c echo wdleng.c; cc -c -O wdleng.c ar rv /lib/libp.a tmpnam.o printf.o ftoa.o clenf.o scan1.o scan2.o \ scan3.o gets.o puts.o cwrd.o maktab.o unget.o getch.o cgetc.o putch.o \ cerror.o copen.o cputc.o makbuf.o rew.o cflush.o ceof.o cerr2.o cexit.o \ cclose.o getvec.o relvec: this command file recompiles the entire system : $1 = {40,45,70} : $2 = {fpp,nofpp} : $3 = {mt,tu} echo RECOMPILE THE ENTIRE SYSTEM echo must run single user as super user echo also do an immediate reboot after completion echo requires about three 3 hours on an 11/45 sh as.rc sh aslib.rc $2 : note: cc, clib and ld repeated to correctly propagate changes sh cc.rc $2 sh clib.rc $2 sh ld.rc sh cc.rc $2 sh clib.rc $2 sh ld.rc sh portc.rc sh cmd1.rc $2 sh cmd2.rc $2 sh cmd3.rc $2 sh cmd4.rc $2 sh cmd5.rc $2 sh cmd6.rc $2 sh yacc.rc sh lex.rc sh sccs.rc $2 sh adb.rc $2 sh agen.rc sh bas.rc sh cref.rc sh dc.rc if -r fc.rc goto rfc echo fc.rc not available echo probably on second RK source pack goto nfc : rfc sh fc.rc : nfc sh fed.rc sh form.rc sh lil.rc sh nroff.rc sh neqn.rc sh tbl.rc sh term.rc sh font.rc sh sno.rc sh tp.rc sh util.rc $3 sh opsys.rc $1 sh io.rc $1 sh unix.rc $1 echo reboot system now!!!! h clib.rc $2 sh ld.rc sh portc.rc sh cmd1.rc $2 sh cmd2.rc $2 sh cmd3.rc $2 sh cmd4.rc $2 sh cmd5.r: command file to creat "tp" command echo echo /bin/tp chdir ../tp echo tp?.s ; as tp?.s ld -s a.out -lc -l mv -f a.out /bin/tp chmod 755 /bin/tp chown bin /bin/tp y on second RK source pack goto nfc : rfc sh fc.rc : nfc sh fed.rc sh form.rc sh lil.rc sh nroff.rc sh neqn.rc sh tbl.rc sh term.rc sh font.rc sh sno.rc sh tp.rc sh util.rc $3 sh opsys.rc $1 sh io.rc $1 sh unix.rc $1 echo reboot system now!!!! h clib.rc $2 sh ld.rc sh portc.rc sh cmd1.rc $2 sh cmd2.rc $2 sh cmd3.rc $2 sh cmd4.rc $2 sh cmd5.r: creat a UNIX system : $1 = {40,45,70} machine echo echo echo NEW UNIX /usr/sys/a.out echo echo configuration files mch.s low.s and conf.c echo from /usr/source/opsys will be used. if $1x = 40x goto 40 if $1x = 45x goto 45 if $1x = 70x goto 70 echo form: sh unix.rc {40,45,70} exit : 40 = m 40 goto cont : 45 : 70 = m 45 : cont chdir ../opsys echo m$1.s; as m$1.s; mv -f a.out /usr/sys/mch.o echo low.s; as low.s; mv -f a.out /usr/sys/low.o echo conf.c; cc -c -O conf.c; mv -f conf.o /usr/sys/conf.o  chdir /usr/sys sh load $m echo new UNIX is in /usr/sys/a.out echo NEW UNIX /usr/sys/a.out echo echo configuration files mch.s low.s and conf.c echo from /usr/source/opsys will be used. if $1x = 40x goto 40 if $1x = 45x goto 45 if $1x = 70x goto 70 echo form: sh unix.rc {40,45,70} exit : 40 = m 40 goto cont : 45 : 70 = m 45 : cont chdir ../opsys echo m$1.s; as m$1.s; mv -f a.out /usr/sys/mch.o echo low.s; as low.s; mv -f a.out /usr/sys/low.o echo conf.c; cc -c -O conf.c; mv -f conf.o /usr/sys/conf.o : creat boot utilities in "/usr/mdec" and "/usr/mdec/tu" : $1 = {mt | ht} tu10 ro tu16 magtape hardware echo echo BOOT utilities - /usr/mdec/ - /usr/mdec/tu/ if $1x = x echo tu10 magtape assumed chdir ../util echo copy.s ; as copy.s ; strip a.out ; mv -f a.out /usr/mdec/tu/copy echo dldr.s ; as dldr.s ; strip a.out ; mv -f a.out /usr/mdec/tu/dldr echo dli.s ; as dli.s ; strip a.out ; mv -f a.out /usr/mdec/tu/dli echo dtf.s ; as dtf.s ; strip a.out ; mv -f a.out /usr/mdec/tu/dtf echo list.s ; as list.s ; strip a.out ; mv -f a.out /usr/mdec/tu/list echo rkf.s ; as rkf.s ; strip a.out ; mv -f a.out /usr/mdec/tu/rkf echo uboot.s ; as uboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/uboot cp /usr/mdec/tu/uboot /usr/mdec/uboot ed - tboot.s /^\.mt/s/[01]/1/ /^\.tc/s/[01]/0/ /^\.tu/s/[01]/0/ w q echo "tboot.s(mt)" ; as tboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/mtboot if $1x != htx cp /usr/mdec/tu/mtboot /usr/mdec/mboot ed - tboot.s /^\.mt/s/[01]/0/ /^\.tc/s/[01]/1/ /^\.tu/s/[01]/0/ w q echo "tboot.s(tc)" ; as tboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/tcboot cp /usr/mdec/tu/tcboot /usr/mdec/tboot ed - tboot.s /^\.mt/s/[01]/0/ /^\.tc/s/[01]/0/ /^\.tu/s/[01]/1/ w q echo "tboot.s(tu)" ; as tboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/tuboot if $1x = htx cp /usr/mdec/tu/tuboot /usr/mdec/mboot ed - hpboot.s /^\.hp/s/[01]/1/ /^\.hs/s/[01]/0/ /^\.rf/s/[01]/0/ /^\.rk/s/[01]/0/ /^\.rp/s/[01]/0/ w q echo "hpboot.s(hp)" ; as hpboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/hpboot ed - hpboot.s /^\.hp/s/[01]/0/ /^\.hs/s/[01]/1/ /^\.rf/s/[01]/0/ /^\.rk/s/[01]/0/ /^\.rp/s/[01]/0/ w q echo "hpboot.s(hs)" ; as hpboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/hsboot ed - hpboot.s /^\.hp/s/[01]/0/ /^\.hs/s/[01]/0/ /^\.rf/s/[01]/1/ /^\.rk/s/[01]/0/ /^\.rp/s/[01]/0/ w q echo "hpboot.s(rf)" ; as hpboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/rfboot ed - hpboot.s /^\.hp/s/[01]/0/ /^\.hs/s/[01]/0/ /^\.rf/s/[01]/0/ /^\.rk/s/[01]/1/ /^\.rp/s/[01]/0/ w q echo "hpboot.s(rk)" ; as hpboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/rkboot ed - hpboot.s /^\.hp/s/[01]/0/ /^\.hs/s/[01]/0/ /^\.rf/s/[01]/0/ /^\.rk/s/[01]/0/ /^\.rp/s/[01]/1/ w q echo "hpboot.s(rp)" ; as hpboot.s ; strip a.out ; mv -f a.out /usr/mdec/tu/rpboot : misc. for /usr/sys and /usr/lib echo load ; cp load /usr/sys/load echo mkconf.c ; cc -O -s mkconf.c mkdata.c ; mv -f a.out /usr/sys/conf/mkconf chdir /usr/mdec/tu chmod 755 copy dldr dli dtf list rkf uboot chown bin copy dldr dli dtf list rkf uboot chmod 755 mtboot tcboot tuboot hpboot hsboot rfboot rkboot rpboot chown bin mtboot tcboot tuboot hpboot hsboot rfboot rkboot rpboot chdir /usr/mdec chmod 755 uboot mboot tboot chown bin uboot mboot tboot chmod 755 /usr/sys/load /usr/sys/conf/mkconf chown bin /usr/sys/load /usr/sys/conf/mkconf cho load ; cp load /usr/sys/load echo mkconf.c ; cc -O -s mkconf.c mkdata.c ; mv -f a.out /usr/sys/conf/mkconf chdir /usr/mdec/tu chmod 755 copy dldr dli dtf list rkf uboot chown bin copy dldr dli dtf list rkf uboot chmod 755 mtboot tcboot tuboot : creat "YACC" compiler compiler echo echo YACC /usr/bin/yacc /lib/liby.a /usr/yacc/yopti /usr/yacc/opar.c chdir ../yacc cc -O -s y?.c mv -f a.out /usr/bin/yacc chmod 755 /usr/bin/yacc; chown bin /usr/bin/yacc echo /lib/liby.a echo main.o; cc -O -c main.c echo parser.o; cc -O -c parser.c echo zinit.o; cc -O -c zinit.c echo zerr.o; cc -O -c zerr.c echo zacc.o; cc -O -c zacc.c ar rv /lib/liby.a main.o parser.o zinit.o zerr.o zacc.o chmod 644 /lib/liby.a chown bin /lib/liby.a echo yopti cc -O -s yopti.c y5.c mv -f a.out /usr/yacc/yopti echo opar.c; cp opar.c /usr/yacc/opar.c rm *.o chdir /usr/yacc chmod 755 yopti chmod 644 opar.c chown bin yopti opar.c : yacc consists of: : /usr/bin/yacc yacc compiler-compiler : /lib/liby.a yacc library : /usr/yacc/yopti optimizer post processor : /usr/yacc/opar.c parcer for optimized tables cc -O -c zerr.c echo zacc.o; cc -O -c zacc.c ar rv /lib/liby.a main.o parser.o zinit.o zerr.o zacc.o chmod 644 /lib/liby.a chown bin /lib/liby.a echo yopti cc -O -s yopti.c y5: command file to create the debugger "adb" echo echo /bin/adb : $1 = {fpp | nofpp} for floating point hardware or not if $1x = x echo nofpp asumed chdir ../adb if $1x = fppx goto fpp echo adb with nofpp cc -s -f -O -n adb1.c adb2.c adb3.c adb4.c goto madb : fpp echo adb with fpp cc -s -O -n adb1.c adb2.c adb3.c adb4.c : madb mv -f a.out /bin/adb rm adb?.o chmod 755 /bin/adb chown bin /bin/adb in.o parser.o zinit.o zerr.o zacc.o chmod 644 /lib/liby.a chown bin /lib/liby.a echo yopti cc -O -s yopti.c y5: shell to install the pgms in /usr/lib/term/ echo echo /usr/lib/term/ chdir ../term echo 300 cc -c 300.c strip 300.o mv -f 300.o /usr/lib/term/300 echo 300S cc -c 300S.c strip 300S.o mv -f 300S.o /usr/lib/term/300S echo 300X cc -c 300X.c strip 300X.o mv -f 300X.o /usr/lib/term/300X echo 300s cc -c 300s.c strip 300s.o mv -f 300s.o /usr/lib/term/300s echo 37 cc -c 37.c strip 37.o mv -f 37.o /usr/lib/term/37 echo 450 cc -c 450.c strip 450.o mv -f 450.o /usr/lib/term/450 echo 450-12 cc -c 450-12.c strip 450-12.o mv -f 450-12.o /usr/lib/term/450-12 echo 450X cc -c 450X.c strip 450X.o mv -f 450X.o /usr/lib/term/450X echo tn300 cc -c tn300.c strip tn300.o mv -f tn300.o /usr/lib/term/tn300 chdir /usr/lib/term chown bin * chmod 755 * X cc -c 300X.c strip 300X.o mv -f 300X.o /usr/lib/term/300X echo 300s cc -c 300s.c strip 300s.o mv -f 300s.o /usr/lib/term/300s echo 37 cc -c 37.c strip 37.o mv -f 37.o /usr/lib/term/37 echo 450 cc -c 450.c strip 450.o mv -f 450.o /usr/lib/term/450 echo 450-12 cc -c 450-12.c strip 450-1: shell to reinstall the pgms in /usr/lib/font echo echo /usr/lib/font/ chdir ../font echo B cc -c B.c strip B.o mv -f B.o /usr/lib/font/B echo CE cc -c CE.c strip CE.o mv -f CE.o /usr/lib/font/CE echo CK cc -c CK.c strip CK.o mv -f CK.o /usr/lib/font/CK echo G cc -c G.c strip G.o mv -f G.o /usr/lib/font/G echo GI cc -c GI.c strip GI.o mv -f GI.o /usr/lib/font/GI echo GM cc -c GM.c strip GM.o mv -f GM.o /usr/lib/font/GM echo I cc -c I.c strip I.o mv -f I.o /usr/lib/font/I echo L cc -c L.c strip L.o mv -f L.o /usr/lib/font/L echo LI cc -c LI.c strip LI.o mv -f LI.o /usr/lib/font/LI echo PA cc -c PA.c strip PA.o mv -f PA.o /usr/lib/font/PA echo PB cc -c PB.c strip PB.o mv -f PB.o /usr/lib/font/PB echo PI cc -c PI.c strip PI.o mv -f PI.o /usr/lib/font/PI echo R cc -c R.c strip R.o mv -f R.o /usr/lib/font/R echo S cc -c S.c strip S.o mv -f S.o /usr/lib/font/S echo SB cc -c SB.c strip SB.o mv -f SB.o /usr/lib/font/SB echo SI cc -c SI.c strip SI.o mv -f SI.o /usr/lib/font/SI echo SM cc -c SM.c strip SM.o mv -f SM.o /usr/lib/font/SM echo UD cc -c UD.c strip UD.o mv -f UD.o /usr/lib/font/UD chdir /usr/lib/font chown bin * chmod 755 * r/lib/font/PA echo PB cc -c PB.c strip PB.o mv -f PB.o /usr/lib/font/PB echo PI cc -c PI.c strip PI.o mv -f PI.o /usr/lib/font/PI echo R cc -c R.c strip R.o mv -f R.o /usr/lib/font/R echo S cc -c S.c strip S.o mv -f S.o /usr/lib/font/S echo SB cc -c SB.c strip SB.o mv -f SB.o /usr/lib/font/SB echo SI cc -c SI.c strip SI.o mv -f SI.o /usr/lib/font/SI echo SM cc -c SM.c strip SM.o mv -f SM.: create the eqn command echo echo /usr/bin/eqn echo this runcom depends on yacc to work. chdir ../neqn yacc e.g cc -O -n e*.c -ly strip a.out mv -f a.out /usr/bin/eqn rm y.tab.c rm *.o chown bin /usr/bin/eqn chmod 755 /usr/bin/eqn usr/lib/font/PI echo R cc -c R.c strip R.o mv -f R.o /usr/lib/font/R echo S cc -c S.c strip S.o mv -f S.o /usr/lib/font/S echo SB cc -c SB.c strip SB.o mv -f SB.o /usr/lib/font/SB echo SI cc -c SI.c strip SI.o mv -f SI.o /usr/lib/font/SI echo SM cc -c SM.c strip SM.o mv -f SM.: shell to recompile and install /usr/bin/tbl echo echo /usr/bin/tbl chdir ../tbl echo tbl cc tbl?.c -lp strip a.out mv -f a.out /usr/bin/tbl rm *.o chmod 755 /usr/bin/tbl chown bin /usr/bin/tbl in /usr/bin/eqn chmod 755 /usr/bin/eqn usr/lib/font/PI echo R cc -c R.c strip R.o mv -f R.o /usr/lib/font/R echo S cc -c S.c strip S.o mv -f S.o /usr/lib/font/S echo SB cc -c SB.c strip SB.o mv -f SB.o /usr/lib/font/SB echo SI cc -c SI.c strip SI.o mv -f SI.o /usr/lib/font/SI echo SM cc -c SM.c strip SM.o mv -f SM.: command file to create the source code control system (sccs) : $1 = {fpp | nofpp} for floating point hardware or not. echo SCCS if $1x != x goto parm echo nofpp assumed goto nofpp : perror echo "usage - sh sccs.rc {fpp | nofpp}" exit : parm if $1 = fpp goto sccs if $1 != nofpp goto perror : nofpp = f -f : sccs chdir /usr/source/sccsutil1 cc -c $f -O dsize.c cc -c -O alloc.c\ bufrd.c\ bufwrt.c\ cat.c\ cindex.c\ clean.c\ copy.c\ dblgtr.c\ dname.c\ equal.c\ exists.c\ exit1.c\ exit2.c\ fatal.c\ getchr.c\ getl.c\ getldr.c\ getlnm.c\ gt.c > /dev/null chdir ../sccsutil2 as - -o putchr.o putchr.s cc -c -O \ move.c\ msg2.c\ patoi.c\ putl.c\ pwldir.c\ remove.c\ rename.c\ same.c\ setsig.c\ size.c\ sname.c\ strf.c\ substr.c\ xcreat.c\ xlink.c\ xopen.c\ xpipe.c\ xwrite.c > /dev/null chdir ../sccscommon cc -c -O \ ctlrec.c\ dohist.c\ dofile.c\ sinit.c\ wrtrec.c\ dor.c\ dohead.c\ rdrec.c\ inbuf.c\ dtcvt.c\ permiss.c\ rdmod.c\ dorelt.c\ rwpfile.c\ outbuf.c\ dodelt.c\ dolist.c\ auxf.c\ delstr.c > /dev/null chdir .. ar r ulib.a \ sccscommon/dodelt.o\ sccscommon/dofile.o\ sccscommon/dohead.o\ sccscommon/dohist.o\ sccscommon/dolist.o\ sccscommon/dor.o\ sccscommon/dorelt.o\ sccscommon/dtcvt.o\ sccscommon/permiss.o\ sccscommon/rdmod.o\ sccscommon/rdrec.o\ sccscommon/rwpfile.o\ sccscommon/sinit.o\ sccscommon/wrtrec.o\ sccscommon/auxf.o\ sccscommon/ctlrec.o\ sccscommon/delstr.o\ sccscommon/inbuf.o\ sccscommon/outbuf.o\ sccsutil2/pwldir.o \ sccsutil1/alloc.o \ sccsutil1/getl.o \ sccsutil2/putl.o \ sccsutil1/bufrd.o \ sccsutil1/bufwrt.o \ sccsutil2/rename.o \ sccsutil2/remove.o \ sccsutil2/xwrite.o\ sccsutil2/xcreat.o > /dev/null ar r ulib.a \ sccsutil2/xopen.o \ sccsutil2/xpipe.o \ sccsutil2/xlink.o \ sccsutil1/dname.o \ sccsutil2/setsig.o \ sccsutil1/fatal.o \ sccsutil1/exit2.o \ sccsutil2/msg2.o \ sccsutil1/clean.o \ sccsutil1/copy.o \ sccsutil1/dblgtr.o \ sccsutil1/dsize.o \ sccsutil1/equal.o \ sccsutil1/exit1.o \ sccsutil1/getchr.o \ sccsutil1/getldr.o \ sccsutil1/getlnm.o \ sccsutil2/move.o \ sccsutil2/patoi.o \ sccsutil2/same.o \ sccsutil2/size.o \ sccsutil2/sname.o \ sccsutil1/exists.o \ sccsutil1/cindex.o \ sccsutil2/substr.o \ sccsutil1/cat.o\ sccsutil1/gt.o\ sccsutil2/strf.o\ sccsutil2/putchr.o > /dev/null rm -f sccsutil1/*.o sccsutil2/*.o sccscommon/*.o > /dev/null chdir sccscmds cc -O -s admin.c ../ulib.a mv -f a.out /usr/bin/admin cc -O -s chghist.c ../ulib.a mv -f a.out /usr/bin/chghist cc -O -s $f delta.c ../ulib.a mv -f a.out /usr/bin/delta cc -O -s get.c ../ulib.a mv -f a.out /usr/bin/get cc -O -s help.c ../ulib.a mv -f a.out /usr/bin/help cc -O -s prt.c ../ulib.a mv -f a.out /usr/bin/prt cc -O -s rmdel.c ../ulib.a mv -f a.out /usr/bin/rmdel cc -O -s what.c ../ulib.a mv -f a.out /usr/bin/what cc -O -s reform.c mv -f a.out /usr/bin/reform cp sccs.hf /usr/lib/sccs.hf rm ../ulib.a chown bin /usr/lib/sccs.hf chmod 644 /usr/lib/sccs.hf chdir /usr/bin chown bin admin chghist delta get help prt rmdel what reform chmod 755 admin chghist delta get help prt rmdel what reform mv -f a.out /usr/bin/get cc -O -s help.c ../ulib.a mv -struct node { struct node *p1; struct node *p2; char typ; char ch; }; int freesize; struct node *lookf; struct node *looks; struct node *lookend; struct node *lookstart; struct node *lookdef; struct node *lookret; struct node *lookfret; int cfail; int rfail; struct node *freelist; struct node *namelist; int lc; struct node *schar; n bin admin chghist delta get help prt rmdel what reform chmod 755 admin chghist delta get help prt rmdel what reform mv -f a.out /usr/bin/get cc -O -s help.c ../ulib.a mv -#include "sno.h" /* * Snobol III */ int freesize; struct node *freespace &end; struct node *freelist 0; int *fault -1; mes(s) { sysput(strstr(s)); } init(s, t) { register struct node *a, *b; a = strstr(s); b = look(a); delete(a); b->typ = t; return(b); } main(argc, argv) char *argv[]; { extern fin, fout; register struct node *a, *b, *c; if(argc > 1) { fin = open(argv[1], 0); if(fin < 0) { mes("cannot open input"); exit(); } } fout = dup(1); lookf = init("f", 0); looks = init("s", 0); lookend = init("end", 0); lookstart = init("start", 0); lookdef = init("define", 0); lookret = init("return", 0); lookfret = init("freturn", 0); init("syspit", 3); init("syspot", 4); a = c = compile(); while (lookend->typ != 2) { a->p1 = b = compile(); a = b; } cfail = 1; a->p1 = 0; if (lookstart->typ == 2) c = lookstart->p2; while (c=execute(c)); flush(); } syspit() { extern fin; register struct node *b, *c, *d; int a; if((a=getchar()) == '\0'){ close(fin); fin = 0; a = getchar(); } if(a == '\n') return(0); b = c = alloc(); while(a != '\n') { c->p1 = d = alloc(); c = d; l: c->ch = a; if(a == '\0') { if(fin) { close(fin); fin = 0; a = getchar(); goto l; } rfail = 1; break; } a = getchar(); } b->p2 = c; if(rfail) { delete(b); b = 0; } return(b); } syspot(string) struct node *string; { register struct node *a, *b, *s; s = string; if (s!=0) { a = s; b = s->p2; while(a != b) { a = a->p1; putchar(a->ch); } } putchar('\n'); } strstr(s) char s[]; { int c; register struct node *e, *f, *d; d = f = alloc(); while ((c = *s++)!='\0') { (e=alloc())->ch = c; f->p1 = e; f = e; } d->p2 = e; return(d); } class(c) { switch (c) { case ')': return(1); case '(': return(2); case '\t': case ' ': return(3); case '+': return(4); case '-': return(5); case '*': return(6); case '/': return(7); case '$': return(8); case '"': case '\'': return(9); case '=': return(10);  case ',': return(11); } return(0); } alloc() { register struct node *f; register int i; extern fout; if (freelist==0) { if (--freesize < 20) { if ((i=sbrk(1200)) == -1) { flush(); write (fout, "Out of free space\n", 18); exit(); } freesize =+ 200; } return(freespace++); } f = freelist; freelist = freelist->p1; return(f); } free(pointer) struct node *pointer; { pointer->p1 = freelist; freelist = pointer; } nfree() { register int i; register struct node *a; i = freesize; a = freelist; while(a) { a = a->p1; i++; } return(i); } look(string) struct node *string; { register struct node *i, *j, *k; k = 0; i = namelist; while (i) { j = i->p1; if (equal(j->p1, string) == 0) return(j); i = (k=i)->p2; } i = alloc(); i->p2 = 0; if (k) k->p2 = i; else namelist = i; j = alloc(); i->p1 = j; j->p1 = copy(string); j->p2 = 0; j->typ = 0; return(j); } copy(string) struct node *string; { register struct node *j, *l, *m; struct node *i, *k;  if (string == 0) return(0); i = l = alloc(); j = string; k = string->p2; while(j != k) { m = alloc(); m->ch = (j=j->p1)->ch; l->p1 = m; l = m; } i->p2 = l; return(i); } equal(string1, string2) struct node *string1, *string2; { register struct node *i, *j, *k; struct node *l; int n, m; if (string1==0) { if (string2==0) return(0); return(-1); } if (string2==0) return(1); i = string1; j = string1->p2; k = string2; l = string2->p2; for(;;) { m = (i=i->p1)->ch; n = (k=k->p1)->ch; if (m>n) return(1); if (mp1; q = s->p2; sign = 1; if (class(p->ch)==5) { /* minus */ sign = -1; if (p==q) return(0); p = p->p1; } loop: m = p->ch - '0'; if (m>9 | m<0) writes("bad integer string"); n = n * 10 + m; if (p==q) return(n*sign); p = p->p1; goto loop; } binstr(binary) { int n, sign; register struct node *m, *p, *q; n = binary; p = alloc(); q = alloc(); sign = 1; if (binary<0) { sign = -1; n = -binary; } p->p2 = q; loop: q->ch = n%10+'0'; n = n / 10; if (n==0) { if (sign<0) { m = alloc(); m->p1 = q; q = m; q->ch = '-'; } p->p1 = q; return(p); } m = alloc(); m->p1 = q; q = m; goto loop; } add(string1, string2) { return(binstr(strbin(string1) + strbin(string2))); }  sub(string1, string2) { return(binstr(strbin(string1) - strbin(string2))); } mult(string1, string2) { return(binstr(strbin(string1) * strbin(string2))); } div(string1, string2) { return(binstr(strbin(string1) / strbin(string2))); } cat(string1, string2) struct node *string1, *string2; { register struct node *a, *b; if (string1==0) return(copy(string2)); if (string2==0) return(copy(string1)); a = copy(string1); b = copy(string2); a->p2->p1 = b->p1; a->p2 = b->p2; free(b); return(a); } dcat(a,b) struct node *a, *b; { register struct node *c; c = cat(a,b); delete(a); delete(b); return(c); } delete(string) struct node *string; { register struct node *a, *b, *c; if (string==0) return; a = string; b = string->p2; while(a != b) { c = a->p1; free(a); a = c; } free(a); } sysput(string) { syspot(string); delete(string); } dump() { dump1(namelist); } dump1(base) struct node *base; { register struct node *b, *c, *e; struct node *d; while (base) { b = base->p1; c = binstr(b->typ); d = strstr(" "); e = dcat(c, d); sysput(cat(e, b->p1)); delete(e); if (b->typ==1) { c = strstr(" "); sysput(cat(c, b->p2)); delete(c); } base = base->p2; } } writes(s) { sysput(dcat(binstr(lc),dcat(strstr("\t"),strstr(s)))); flush(); if (cfail) { dump(); flush(); exit(); } while(getc()); while (compile()); flush(); exit(); } getc() { register struct node *a; static struct node *line; static linflg; while (line==0) { line = syspit(); if(rfail) { cfail++; writes("eof on input"); } lc++; } if (linflg) { line = 0; linflg = 0; return(0); } a = line->p1; if (a==line->p2) { free(line); linflg++; } else line->p1 = a->p1; return(a); } ut(dcat(binstr(lc),dcat(strstr("\t"),strstr(s)))); flush(); if (cfail) { dump(); flush(); exit(); } while(getc()); while (compile()); flush(); exit(); } getc() { register struct node *a; static struct node *line; static linflg; while (line==0) { line = syspit(); if(#include "sno.h" compon() { register struct node *a, *b; register int c; static next; if (next == 0) schar = getc(); else next = 0; if (schar == 0) { (a=alloc())->typ = 0; return(a); } switch (class(schar->ch)) { case 1: schar->typ = 5; return(schar); case 2: schar->typ = 16; return(schar); case 3: a = schar; for(;;) { schar = getc(); if (schar == 0) { a->typ = 0; return(a); } if (class(schar->ch) != 3) break; free(schar); } next = 1; a->typ = 7; return(a); case 4: schar->typ = 8; return(schar); case 5: schar->typ = 9; return(schar); case 6: a = schar; schar = getc(); if (class(schar->ch) == 3) a->typ = 10; else a->typ = 1; next = 1; return(a); case 7: a = schar; schar = getc(); if (class(schar->ch) == 3) a->typ = 11; else a->typ = 2; next = 1; return(a); case 8: schar->typ = 12; return(schar); case 9: c = schar->ch; a = getc(); if(a == 0) goto lerr; b = schar; if(a->ch == c) { free(schar); a->typ = 15; a->p1 = 0; return(a); } b->p1 = a; for(;;) { schar = getc(); if (schar == 0) lerr: writes("illegal literal string"); if(schar->ch == c) break; a->p1 = schar; a = schar; } b->p2 = a; schar->typ = 15; schar->p1 = b; return(schar); case 10: schar->typ = 3; return(schar); case 11: schar->typ = 4; return(schar); } b = alloc(); b->p1 = a = schar; schar = getc(); while(schar!=0 & !class(schar->ch)) { a->p1 = schar; a = schar; schar = getc(); } b->p2 = a; next = 1; a = look(b); delete(b); b = alloc(); b->typ = 14; b->p1 = a; return(b); } nscomp() { register struct node *c; while((c=compon())->typ == 7) free(c); return(c); } push(stack) { register struct node *a; (a=alloc())->p2 = stack; return(a); } pop(stack) struct node *stack; { register struct node *a, *s; s = stack; if (s == 0) writes("pop"); a = s->p2; free(s); return(a); } expr(start, eof, e) struct node *e; { register struct node *stack, *list, *comp; int operand, op, space, op1; struct node *a, *b, *c; int d; list = alloc(); e->p2 = list; stack = push(0); stack->typ = eof; operand = 0; space = start; l1: if (space) { comp = space; space = 0; } else comp = compon(); l3: op = comp->typ; switch (op) { case 7: space = 1; free(comp); comp = compon(); goto l3; case 10: if (space == 0) { comp->typ = 1; goto l3; } case 11: if (space == 0) { comp->typ = 2; goto l3; } case 8: case 9: if (operand == 0) writes("no operand preceding operator"); operand = 0; goto l5; case 14: case 15: if (operand == 0) { operand = 1; goto l5; } if (space == 0) goto l7; goto l4; case 12: if (operand == 0) goto l5; if (space) goto l4; l7: writes("illegal juxtaposition of operands"); case 16: if (operand == 0) goto l5; if (space) goto l4; b = compon(); op = comp->typ = 13; if (b->typ == 5) { comp->p1 = 0; goto l10; } comp->p1 = a = alloc(); b = expr(b, 6, a); while((d=b->typ) == 4) { a->p1 = b; a = b; b = expr(0, 6, a); } if (d != 5) writes("error in function"); a->p1 = 0; l10: free(b); goto l6; l4: space = comp; op = 7; operand = 0; goto l6; } if (operand==0) writes("no operand at end of expression"); l5: space = 0; l6: op1 = stack->typ; if (op > op1) { stack = push(stack); if (op == 16) op = 6; stack->typ = op; stack->p1 = comp; goto l1; } c = stack->p1; stack = pop(stack); if (stack == 0) { list->typ = 0; return(comp); } if (op1 == 6) { if (op != 5) writes("too many ('s"); goto l1; } if (op1 == 7) c = alloc(); list->typ = op1; list->p2 = c->p1; list->p1 = c; list = c; goto l6; } match(start, m) struct node *m; { register struct node *list, *comp, *term; struct node *a; int b, bal; term = bal = 0; list = alloc(); m->p2 = list; comp = start; if (!comp) comp = compon(); goto l2; l3: list->p1 = a = alloc(); list = a; l2: switch (comp->typ) { case 7: free(comp); comp = compon(); goto l2; case 12: case 14: case 15: case 16: term = 0; comp = expr(comp, 6, list); list->typ = 1; goto l3; case 1: free(comp); comp = compon(); bal = 0; if (comp->typ == 16) { bal = 1; free(comp); comp = compon(); } a = alloc(); b = comp->typ; if (b == 2 | b == 5 | b == 10 | b == 1) a->p1 = 0; else { comp = expr(comp, 11, a); a->p1 = a->p2; } if (comp->typ != 2) { a->p2 = 0; } else { free(comp); comp = expr(0, 6, a); } if (bal) { if (comp->typ != 5) goto merr; free(comp); comp = compon(); } b = comp->typ; if (b != 1 & b != 10) goto merr; list->p2 = a; list->typ = 2; a->typ = bal; free(comp); comp = compon(); if(bal) term = 0; else term = list; goto l3; } if(term) term->typ = 3; list->typ = 0; return(comp); merr: writes("unrecognized component in match"); } compile() { register struct node *b, *comp; struct node *r, *l, *xs, *xf, *g; register int a; int m, t, as; m = l = as = xs = xf = t = 0; comp = compon(); a = comp->typ; if (a == 14) { l = comp->p1; free(comp); comp = compon(); a = comp->typ; } if (a != 7) writes("no space beginning statement"); free(comp); if (l == lookdef) goto def; comp = expr(0, 11, r=alloc()); a = comp->typ; if (a == 0) goto asmble; if (a == 2) goto xfer; if (a == 3) goto assig; m = alloc(); comp = match(comp, m); a = comp->typ; if (a == 0) goto asmble; if (a == 2) goto xfer; if (a == 3) goto assig; writes("unrecognized component in match"); assig: free(comp); comp = expr(0, 6, as=alloc()); a = comp->typ; if (a == 0) goto asmble; if (a == 2) goto xfer; writes("unrecognized component in assignment"); xfer: free(comp); comp = compon(); a = comp->typ; if (a == 16) goto xboth; if (a == 0) { if (xs!=0 | xf!=0) goto asmble; goto xerr; } if (a != 14) goto xerr; b = comp->p1; free(comp); if (b == looks) goto xsuc; if (b == lookf) goto xfail; xerr: writes("unrecognized component in goto"); xboth: free(comp); xs = alloc(); xf = alloc(); comp = expr(0, 6, xs); if (comp->typ != 5) goto xerr; xf->p2 = xs->p2; comp = compon(); if (comp->typ != 0) goto xerr; goto asmble; xsuc: if(xs) goto xerr; comp = compon(); if (comp->typ != 16) goto xerr; comp = expr(0, 6, xs=alloc()); if (comp->typ != 5) goto xerr; goto xfer; xfail: if (xf) goto xerr; comp = compon(); if (comp->typ != 16) goto xerr; comp = expr(0, 6, xf=alloc()); if (comp->typ != 5) goto xerr; goto xfer; asmble: if(l) { if (l->typ) writes("name doubly defined"); l->p2 = comp; l->typ = 2; /* type label;*/ } comp->p2 = r; if (m) { t++; r->p1 = m; r = m; } if (as) { t =+ 2; r->p1 = as; r = as; } (g=alloc())->p1 = 0; if (xs) { g->p1 = xs->p2; free(xs); } g->p2 = 0; if (xf) { g->p2 = xf->p2; free(xf); } r->p1 = g; comp->typ = t; comp->ch = lc; return(comp); def: r = nscomp(); if (r->typ != 14) goto derr; l = r->p1; if (l->typ) writes("name doubly defined"); l->typ = 5; /*type function;*/ a = r; l->p2 = a; r = nscomp(); l = r; a->p1 = l; if (r->typ == 0) goto d4; if (r->typ != 16) goto derr; d2: r = nscomp(); if (r->typ != 14) goto derr; a->p2 = r; r->typ = 0; a = r; r = nscomp(); if (r->typ == 4) { free(r); goto d2; } if (r->typ != 5) goto derr; free(r); if ((r=compon())->typ != 0) goto derr; free(r); d4: r = compile(); a->p2 = 0; l->p1 = r; l->p2 = 0; return(r); derr: writes("illegal component in define"); } ined"); l->typ = 5; /*type function;*/ a = r; l->p2 = a; r = nscomp(); l = r; a->p1 = l; if (r->typ == 0) goto d4; if (r->typ != 16) goto derr; d2: r = nscomp(); if (r->typ != 14) goto derr; a->p2 = r; r->typ = 0; a = r; r = nscomp(); if (r->typ == 4) { free(r); goto d2; } if (r->typ != 5) goto derr; free(r); if ((r=compon())->typ != 0) goto derr; free(r); d4: r = compile(); a->p2 = 0; l->p1 = r; l->p2 = 0; return(r); derr:#include "sno.h" /* * sno3 */ bextend(str, last) struct node *str, *last; { register struct node *a, *s; register int b; int c, d; s = str; if ((c = s->p1) == 0) goto bad; b = d = 0; a = s->p2; if(a == 0) { a = c; goto eb2; } eb1: if (a == last) goto bad; a = a->p1; eb2: d++; c = class(a->ch); if (c == 1) { /* rp */ if (b == 0) goto bad; b--; goto eb3; } if (c == 2) { /* lp */ b++; goto eb1; } eb3: if (b == 0) { s->p2= a; return(d); } goto eb1; bad: return(0); } ubextend(str, last) struct node *str, *last; { register struct node *a, *b, *s; s = str; a = s->p1; if(a == 0) goto bad; b = s->p2; if(b == 0) goto good; if (b == last) goto bad; a = b->p1; good: s->p2 = a; return(1); bad: return(0); } search(arg, r) struct node *arg, *r; { struct node *list, *back, *str, *etc, *next, *last, *base, *e; register struct node *a, *b, *var; int c, d; a = arg->p2; list = base = alloc(); last = next = 0; goto badv1; badvanc: a = a->p1; if (a->typ == 0) { list->p1 = 0; if (rfail == 1) { a = 0; goto fail; } list = base; if (r == 0) next = last = 0; else { next = r->p1; last = r->p2; } goto adv1; } b = alloc(); list->p1 = b; list = b; badv1: list->p2 = back = alloc(); back->p1 = last; b = a->p2; c = a->typ; list->typ = c; if (c < 2) { back->p2 = eval(b, 1); goto badvanc; } last = list; str = alloc(); etc = alloc(); back->p2 = var = alloc(); var->typ = b->typ; var->p1 = str; var->p2 = etc; e = b->p1; if (e == 0) etc->p1 = 0; else etc->p1 = eval(e, 0); e = b->p2; if (e == 0) etc->p2 = 0; else { e = eval(e, 1); etc->p2 = strbin(e); delete(e); } goto badvanc; retard: a = back->p1; if (a == 0) { rfail = 1; goto fail; } list = a; back = list->p2; var = back->p2; str = var->p1; etc = var->p2; if (etc->p2) goto retard; if (var->typ == 1) { if (bextend(str, last) == 0) goto retard; goto adv0; } if (ubextend(str, last) == 0) goto retard; adv0: a = str->p2; adv01: if (a == last) next = 0; else next = a->p1; advanc: a = list->p1; if (a == 0) { a = alloc(); if (r == 0) { a->p1 = a->p2 = 0; goto fail; } b = r->p1; a->p1 = b; if (next == 0) { a->p2 = r->p2; goto fail; } while(1) { e = b->p1; if (e == next) { a->p2 = b; goto fail; } b = e; } } list = a; adv1: back = list->p2; var = back->p2; d = list->typ; if(d < 2) { if (var == 0) goto advanc; if (next == 0) goto retard; a = next; b = var->p1; e = var->p2; while(1) { if (a->ch != b->ch) goto retard; if (b == e) goto adv01; if (a == last) goto retard; a = a->p1; b = b->p1; } } str = var->p1; etc = var->p2; str->p1 = next; str->p2 = 0; c = etc->p2; if (var->typ == 1) { d = bextend(str, last); if (d == 0) goto retard; if (c == 0) goto adv0; while(1) { c =- d; if (c == 0) goto adv0; if (c < 0) goto retard; d = bextend(str, last); if (d == 0) goto retard; } } if (c == 0) { if(d==3 & next!=0) { str->p2 = last; goto adv0; } goto advanc; } while(c--) if (ubextend(str, last) == 0) goto retard; goto adv0; fail: list = base; goto f1; fadv: free(back); b = list->p1; free(list); if (b == 0) return(a); list = b; f1: back = list->p2; var = back->p2; if (list->typ < 2) { delete(var); goto fadv; } str = var->p1; etc = var->p2; if (a != 0 & etc->p1 != 0) { if (str->p2 == 0) { free(str); str = 0; } assign(etc->p1, copy(str)); } if (str) free(str); free(etc); free(var); goto fadv; } 0; } goto advanc; } while(c--) if (ubextend(str, last) == 0) goto retard; goto adv0; fail: list = base; goto f1; fadv: free(back); b = list->p1; free(list); if (b == 0) return(a); list = b; f1: back = list->p2; var = back->p2; if (list->typ < 2) { delete(var); goto fadv; } str = var->p1; etc = var->p2; if (a != 0 & etc->p1 != 0) { if (str->p2 == 0) { free(str); str = 0; } assign(etc->p1, copy(str)); } #include "sno.h" /* * sno4 */ and(ptr) struct node *ptr; { register struct node *a, *p; p = ptr; a = p->p1; if (p->typ == 0) { switch (a->typ) { case0: case 0: a->typ = 1; case 1: goto l1; case 3: flush(); return(syspit()); case 5: a = a->p2->p1; goto l1; case 6: return(binstr(nfree())); } writes("attempt to take an illegal value"); goto case0; l1: a = copy(a->p2); } return(a); } eval(e, t) struct node *e; { struct node *list, *a2, *a3, *a4, *a3base;  register struct node *a1, *stack, *op; if (rfail == 1) return(0); stack = 0; list = e; goto l1; advanc: list = list->p1; l1: op = list->typ; switch (op) { default: case 0: if (t == 1) { a1 = and(stack); goto e1; } if (stack->typ == 1) writes("attempt to store in a value"); a1 = stack->p1; e1: stack = pop(stack); if (stack) writes("phase error"); return(a1); case 12: a1 = and(stack); stack->p1 = look(a1); delete(a1); stack->typ = 0; goto advanc; case 13:  if (stack->typ) writes("illegal function"); a1 = stack->p1; if (a1->typ!=5) writes("illegal function"); a1 = a1->p2; op = a1->p1; a3base = a3 = alloc(); a3->p2 = op->p2; op->p2 = 0; a1 = a1->p2; a2 = list->p2; f1: if (a1!=0 & a2!=0) goto f2; if (a1!=a2) writes("parameters do not match"); op = op->p1; goto f3; f2: a3->p1 = a4 = alloc(); a3 = a4; a3->p2 = and(a1); assign(a1->p1, eval(a2->p2, 1));/* recursive */ a1 = a1->p2; a2 = a2->p1; goto f1; f3: op = execute(op); /* recursive */ if (op) goto f3; a1 = stack->p1->p2; op = a1->p1; a3 = a3base; stack->p1 = op->p2; stack->typ = 1; op->p2 = a3->p2; f4: a4 = a3->p1; free(a3); a3 = a4; a1 = a1->p2; if (a1 == 0) goto advanc; assign(a1->p1, a3->p2); goto f4; case 11: case 10: case 9: case 8: case 7: a1 = and(stack); stack = pop(stack); a2 = and(stack); a3 = doop(op, a2, a1); delete(a1); delete(a2); stack->p1 = a3; stack->typ = 1; goto advanc; case 15: a1 = copy(list->p2); a2 = 1; goto l3; case 14: a1 = list->p2; a2 = 0; l3: stack = push(stack); stack->p1 = a1; stack->typ = a2; goto advanc; } } doop(op, arg1, arg2) { register int a1, a2; a1 = arg1; a2 = arg2; switch (op) { case 11: return(div(a1, a2)); case 10: return(mult(a1, a2)); case 8: return(add(a1, a2)); case 9: return(sub(a1, a2)); case 7: return(cat(a1, a2)); } return(0); } execute(e) struct node *e; { register struct node *r, *b, *c; struct node *m, *ca, *d, *a; r = e->p2; lc = e->ch; switch (e->typ) { case 0: /* r g */ a = r->p1; delete(eval(r->p2, 1)); goto xsuc; case 1: /* r m g */ m = r->p1; a = m->p1; b = eval(r->p2, 1); c = search(m, b); delete(b); if (c == 0) goto xfail; free(c); goto xsuc; case 2: /* r a g */ ca = r->p1; a = ca->p1; b = eval(r->p2, 0); assign(b, eval(ca->p2, 1)); goto xsuc; case 3: /* r m a g */ m = r->p1; ca = m->p1; a = ca->p1; b = eval(r->p2, 0); d = search(m, b->p2); if (d == 0) goto xfail; c = eval(ca->p2, 1); if (d->p1 == 0) { free(d); assign(b, cat(c, b->p2)); delete(c); goto xsuc; } if (d->p2 == b->p2->p2) { assign(b, c); free(d); goto xsuc; } (r=alloc())->p1 = d->p2->p1; r->p2 = b->p2->p2; assign(b, cat(c, r)); free(d); free(r); delete(c); goto xsuc; } xsuc: if (rfail) goto xfail; b = a->p1; goto xboth; xfail: rfail = 0; b = a->p2; xboth: if (b == 0) { return(e->p1); } b = eval(b, 0); if (b == lookret) return(0); if (b == lookfret) { rfail = 1; return(0); } if (b->typ!=2) writes("attempt to transfer to non-label"); return(b->p2); } assign(adr, val) struct node *adr, *val; { register struct node *a, *addr, *value; addr = adr; value = val; if (rfail == 1) { delete(value); return; } switch (addr->typ) { default: writes("attempt to make an illegal assignment"); case 0: addr->typ = 1; case 1: delete(addr->p2); addr->p2 = value; return; case 4: sysput(value); return; case 5: a = addr->p2->p1; delete(a->p2); a->p2 = value; return; } } =2) writes("attempt to transfer to non-label"); return(b->p2); } assign(adr, val) struct node *adr, *val; { register struct node *a, *addr, *value; addr = adr; value = val; if (rfail == 1) { delete(value); return; } switch (addr->typ) { default: writes("attempt to make an illegal assignment"); case 0: addr->typ = 1; case 1: delete(addr->p2); addr->p2 = value; return; case 4: sysput(value); return# define MAXLIN 200 # define MAXHEAD 30 # define MAXCOL 20 # define MAXCHS 2000 # define CLLEN 10 extern int nlin, ncol, iline, nclin, nslin; extern int style[MAXHEAD][MAXCOL]; extern int ctop[MAXHEAD][MAXCOL]; extern char font[MAXHEAD][MAXCOL][2]; extern char csize[MAXHEAD][MAXCOL][4]; extern char cll[MAXCOL][CLLEN]; extern int stynum[]; extern int F1, F2; extern int lefline[MAXHEAD][MAXCOL]; extern int fullbot[]; extern int instead[]; extern int expflg; extern int ctrflg; extern int evenflg; extern int evenup[]; extern int boxflg; extern int dboxflg; extern int tab; extern int allflg; extern int textflg; struct colstr {char *col, *rcol;}; extern struct colstr *table[]; extern char *cspace, *cstore; extern char *exstore, *exlim; extern int sep[]; extern int used[], lused[], rused[]; extern int linestop[]; extern int leftover; extern char *last, *ifile; extern int cin, cout; extern int texname; # define CRIGHT 80 # define CLEFT 40 # define CMID 60 # define S1 31 # define S2 32 # define TMP 38 # define SF 35 # define SIND 37 /* this refers to the relative position of lines */ # define LEFT 1 # define RIGHT 2 # define THRU 3 # define TOP 1 # define BOT 2 ct colstr *table[]; extern char *cspace, *cstore; extern char *exstore, *exlim; extern int sep[]; extern int used[], lused[], rused[]; extern int linestop[]; extern int leftover; extern char *last, *ifile; extern int cin, cout; extern int texname; # define CRIGHT 80 # define CLEFT 40 # define CMID 60 # define S1 31 # define S2 32 # define TMP 38 # define SF 35 # # include "tbl.c" int expflg 0; int ctrflg 0; int boxflg 0; int dboxflg 0; int tab '\t'; int evenup[MAXCOL], evenflg; int F1 0; int F2 0; int allflg 0; int leftover 0; int textflg 0; char *cstore, *cspace; char *last; struct colstr *table[MAXLIN]; int style[MAXHEAD][MAXCOL]; int ctop[MAXHEAD][MAXCOL]; char font[MAXHEAD][MAXCOL][2]; char csize[MAXHEAD][MAXCOL][4]; int lefline[MAXHEAD][MAXCOL]; char cll[MAXCOL][CLLEN]; int stynum[MAXLIN+1]; int nslin, nclin; int sep[MAXCOL]; int fullbot[MAXLIN]; int instead[MAXLIN]; int used[MAXCOL], lused[MAXCOL], rused[MAXCOL]; int linestop[MAXLIN]; int nlin, ncol; int iline 1; char *ifile "Input"; int texname 'a'; char *exstore, *exlim; int textflg 0; char *cstore, *cspace; char *last; struct colstr *table[MAXLIN]; int style[MAXHEAD][MAXCOL]; int ctop[MAXHEAD][MAXCOL]; char font[MAXHEAD][MAXCOL][2]; char csize[MAXHEAD][MAXCOL][4]; int lefline[MAXHEAD][MAXCOL]; char cll[MAXCOL][CLLEN]; int stynum[MAXLIN+1]; int nslin, nclin; int sep[MAXCOL]; int fullbot[MAXLIN]; int instead# # include "tbl.c" # define BROKPIPE 13 # ifdef unix # define MACROS "/usr/lib/tmac.s" # endif # ifdef gcos # define MACROS "cc/troff/smac" # endif # define ever (;;) main(argc,argv) char *argv[]; { #ifdef gcos if(!intss()) cout = copen("*qq", 'w'); /* default media code is type 5 */ #endif # ifdef unix int badsig(); signal(BROKPIPE, badsig); # endif cexit(tbl(argc,argv)); } tbl(argc,argv) char *argv[]; { char line[512]; for ever { if (argc>1) { argc--; argv++; if (match("-ms", *argv)) *argv = MACROS; cin = copen(ifile= *argv, 'r'); iline=1; if (cin < 0) { printf(2, "can't open input file %s\n", ifile); return(1); } } while (gets1(line)) { puts(line); if (prefix(".TS", line)) tableput(); } cclose(cin); if (argc <= 1) break; } return(0); } # ifdef unix badsig() { signal(BROKPIPE, 1); cexit(0); } # endif IPE, badsig); # endif cexit(tbl(argc,argv)); } tbl(argc,argv) char *argv[]; { char line[512]; for ever { if (argc>1) { argc--; argv++; if (match("-ms", *argv)) *argv# include "tbl.c" tableput() { savefill(); ifdivert(); getcomm(); getspec(); gettbl(); getstop(); checkuse(); choochar(); maktab(); runout(); release(); rstofill(); endoff(); } if (prefix(".TS", line)) tableput(); } cclose(cin); if (argc <= 1) break; } return(0); } # ifdef unix badsig() { signal(BROKPIPE, 1); cexit(0); } # endif IPE, badsig); # endif cexit(tbl(argc,argv)); } tbl(argc,argv) char *argv[]; { char line[512]; for ever { if (argc>1) { argc--; argv++; if (match("-ms", *argv)) *argv# include "tbl.c" struct optstr {char *optnam; int *optadd;} options [] { "expand", &expflg, "center", &ctrflg, "box", &boxflg, "allbox", &allflg, "doublebox", &dboxflg, "frame", &boxflg, "doubleframe", &dboxflg, "tab", &tab, 0,0}; getcomm() { char line[200], *cp; struct optstr *lp; int c; for(lp= options; lp->optnam; lp++) *(lp->optadd) = 0; texname='a'; tab = '\t'; gets1(line); /* see if this is a command line */ if (index(line,';') < 0) { backrest(line); return; } for(cp=line; (c = *cp) != ';'; cp++) { if (!letter(c)) continue; for(lp= options; lp->optadd; lp++) { if (prefix(lp->optnam, cp)) { *(lp->optadd) = 1; while (letter(*cp)) cp++; if (lp->optadd == &tab) { while (*cp==' ')cp++; if (*cp == '('){ *(lp->optadd) = *++cp; cp++; } } break; } } if (letter(*cp)) error("Illegal option"); cp--; } cp++; backrest(cp); return; } backrest(cp) char *cp; { char *s; for(s=cp; *s; s++); un1getc('\n', cin); while (s>cp) un1getc(*--s, cin); return; } +) { if (!letter(c)) continue; for(lp= options; lp->optadd; lp++) { if (prefix(lp->optnam, cp)) { *(lp->optadd) = 1; while (letter(*cp)) cp++; if (lp->optadd == &tab) { while (*cp==' ')cp++; if (*cp == '('){ *(lp->optadd) = *++cp; cp++; } } break; } } if (letter(*cp)) error("Illegal option"); cp--; } cp++; backrest(cp); return; } backrest(cp) char *cp; { char *s; for(s=cp; *s; s++); un1getc('\n', cin); while (s>cp) un1getc(*--s, cin); re# include "tbl.c" getspec() { int icol, i; for(icol=0; icol0) ncol++; if(sawchar) nclin++; if (nclin>=MAXHEAD) error("too many lines in specification"); icol=0; if (ncol==0 || nclin==0) error("no specification"); if (c== '.') { while ((c=get1char()) && c != '\n'); /* fix up sep - default is 3 except at edge */ for(icol=0; icol<ncol; icol++) if (sep[icol]<0) sep[icol] = icol+1=MAXCOL) error("too many columns in table"); sawchar=1; continue; case 'b': case 'i': c =+ 'A'-'a'; case 'B': case 'I': if (icol==0) continue; snp=font[nclin][icol-1]; snp[0]=c; snp[1]=0; continue; case 't': case 'T': if (icol>0) ctop[nclin][icol-1] = 1; continue; case 'f': case 'F': if (icol==0) continue; snp=font[nclin][icol-1]; snp[0]=snp[1]=0; for(temp=snp+2; snptemp) break; else *snp++=c; else if (digit(c)) *snp++ = c; else break; if (snp-temp>4) error("point size too large"); } *snp=0; un1getc(c,cin); continue; case 'w': case 'W': snp = cll [icol-1]; if (*snp) { printf (2, "Ignored second width specification"); continue; } stopc=0; while (c = get1char()) { if (snp==cll[icol-1] && c=='(') { stopc = ')'; continue; } if ( !stopc && (c>'9' || c< '0')) break; if (stopc && c== stopc) break; *snp++ =c; } *snp=0; if (snp-cll[icol-1]>CLLEN) error ("column width too long"); if (!stopc) un1getc(c); continue; case 'e': case 'E': if (icol<1) continue; evenup[icol-1]=1; evenflg=1; continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': sn[0] = c; snp=sn+1; while (digit(*snp++ = c = get1char())) ; un1getc(c,cin); sep[icol-1] = max(sep[icol-1], numb(sn)); continue; case '|': lefline[nclin][icol]++; continue; } } error("EOF reading table specification"); } too long"); if (!stopc) un1getc(c); continue; case 'e': case 'E': if (# include "tbl.c" gettbl() { int icol, ch; cstore=cspace= chspace(); textflg=0; for (nlin=nslin=0; gets1(cstore); nlin++) { stynum[nlin]=nslin; if (prefix(".TE", cstore)) { leftover=0; break; } if (prefix(".TC", cstore) || prefix(".T&", cstore)) { readspec(); nslin++; } if (nlin>=MAXLIN) { leftover=1; break; } fullbot[nlin]=0; if (cstore[0] == '.' && letter(cstore[1])) { instead[nlin] = cstore; while (*cstore++); continue; } else instead[nlin] = 0; while (nodata(nlin)) { if (ch = oneh(nlin)) fullbot[nlin]= ch; nlin++; nslin++; instead[nlin]=fullbot[nlin]=0; } table[nlin] = alocv(ncol*sizeof(table[0][0])); if (cstore[1]==0) switch(cstore[0]) { case '_': fullbot[nlin]= '-'; continue; case '=': fullbot[nlin]= '='; continue; } stynum[nlin] = nslin; nslin = min(nslin+1, nclin-1); for (icol = 0; icol MAXCHS) cstore = cspace = chspace(); } last = cstore; permute(); if (textflg) untext(); return; } nodata(il) { int c; for (c=0; c=\\n(%d .nr %d \\n(%du+2n\n",S2,icol+CRIGHT,icol+CRIGHT,S2); if (doubled[icol]) { printf(".nr %d \\n(%d\n", icol+CMID, S1); printf(".nr %d \\n(%d+\\n(%d\n",TMP,icol+CMID,S2); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n",TMP,icol+CRIGHT,icol+CRIGHT,TMP); printf(".if \\n(%d<\\n(%d .nr %d +(\\n(%d-\\n(%d)/2\n",TMP,icol+CRIGHT,icol+CMID,icol+CRIGHT,TMP); } if (cll[icol][0]) { printf(".nr %d %sn\n", TMP, cll[icol]); printf(".if \\n(%d<\\n(%d .nr %d \\n(%d\n",icol+CRIGHT, TMP, icol+CRIGHT, TMP); } for(ilin=0; ilin=0; ik--) printf("-\\n(%d",CRIGHT+icol-ik); printf("\n"); printf(".if \\n(%d>0 .nr %d \\n(%d/%d\n", TMP, TMP, TMP, k); printf(".if \\n(%d<0 .nr %d 0\n", TMP, TMP); for(ik=1; ik<=k; ik++) { if (doubled[icol-k+ik]) printf(".nr %d +\\n(%d/2\n", icol-k+ik+CMID, TMP); printf(".nr %d +\\n(%d\n", icol-k+ik+CRIGHT, TMP); } } } /* if even requested, make all columns widest width */ # define TMP1 S1 # define TMP2 S2 if (evenflg) { printf(".nr %d 0\n", TMP); for(icol=0; icol\\n(%d .nr %d \\n(%d\n", icol+CRIGHT, TMP, TMP, icol+CRIGHT); } for(icol=0; icol0 .nr %d +12u\n",icol+CMID, icol+CMID); } tsep=sep[icol]; } printf(".nr TW \\n(%d\n", ncol+CRIGHT-1); if (boxflg || allflg || dboxflg) printf(".nr TW +%d*\\n(%d\n", sep[ncol-1], TMP); printf(".if t .if (\\n(TW+\\n(.o)>7.75i .tm Table at line %d file %s is too wide - \\n(TW units\n", iline, ifile); return; } wide(s, fn, size) char *s, *size, *fn; { if (point(s)) { printf("\\w%c", F1); if (*fn>0) putfont(fn); if (*size) putsize(size); printf("%s", s); if (*fn>0) putfont("P"); if (*size) putsize("0"); printf("%c",F1); } else printf("\\n(%c-", s); } ol]; } printf(".nr TW \\n(%d\n", ncol+CRIGHT-1); if (boxflg || allflg || dbox# include "tbl.c" # define realsplit ((ct=='a'||ct=='n') && table[i][c].rcol) runout() { int i, c; if (boxflg || allflg || dboxflg) need(); if (ctrflg) { printf(".nr #I \\n(.i\n"); printf(".in +(\\n(.lu-\\n(TWu-\\n(.iu)/2u\n"); } printf(".fc %c %c\n", F1, F2); printf(".nr #T 0\n"); deftail(); for(i=0; i0 .nr #%c \\n(#T\n",linestop[i]+'a'-1); if (boxflg || allflg || dboxflg) /* bottom of table line */ if (fullbot[nlin-1]==0) { printf(".if \\n(T. .vs2p\n"); printf(".if \\n(T. "); drawline(nlin-1,0,ncol, dboxflg ? '=' : '-',1); printf("\n.if \\n(T. .vs\n"); /* T. is really an argument to a macro but because of eqn we don't dare pass it as an argument and reference by $1 */ } for(c=0; c=0) { printf(".if \\n(#%c>0 .sp -1\n",linestop[lf]+'a'-1); printf(".if \\n(#%c>0 ", linestop[lf]+'a'-1); tohcol(c); drawvert(lf, nlin-1, c, lwid);  printf("\\h'|\\n(TWu'\n"); } } if (boxflg || allflg || dboxflg) /* right hand line */ { printf(".if \\n(#a>0 .sp -1\n"); printf(".if \\n(#a>0 \\h'|\\n(TWu'"); drawvert (0, nlin-1, ncol, dboxflg? 2 : 1); printf("\n"); } printf("..\n"); printf(".ec\n"); } e by $1 */ } for(c=0; c=0) { printf(".if \\n(#%c>0 .sp -1\n",linestop[lf]+'a'-1); printf(".if \\n(#%c>0 ", linestop[lf]+'a'-1); tohcol(c); drawvert(lf, nlin-1, c, lwid); # include "tbl.c" # define realsplit ((ct=='a'||ct=='n') && table[nl][c].rcol) int watchout; int once; putline(i, nl) /* i is line number for deciding format */ /* nl is line number for finding data usually identical */ { int c, lf, ct, form, lwid, vspf; char *s, *size, *fn; watchout=vspf=0; if (i==0) once=0; if (i==0 && ( allflg || boxflg || dboxflg)) fullwide(0, dboxflg? '=' : '-'); if (instead[nl]==0 && fullbot[nl] ==0) for(c=0; c=0) if (vspen(table[lf][c].col)) vspf=1; } if (vspf) { printf(".nr #^ \\n(\\*(#du\n"); printf(".nr #- \\n(#^\n"); /* current line position relative to bottom */ } vspf=0; for(c=0; c=0 && vspen(table[lf][c].col)) printf(".if (\\n(%c|+\\n(^%c-1v)>\\n(#- .nr #- +(\\n(%c|+\\n(^%c-\\n(#--1v)\n",s,'a'+c,s,'a'+c); else printf(".if (\\n(%c|+\\n(#^-1v)>\\n(#- .nr #- +(\\n(%c|+\\n(#^-\\n(#--1v)\n",s,s); } if (instead[nl]) { puts(instead[nl]); return; } if (fullbot[nl]) { switch (ct=fullbot[nl]) { case '=': case '-': fullwide(nl,ct); } return; } if (allflg && once>0 ) fullwide(i,'-'); once=1; runtabs(i); if (allh(i)) printf(".vs 2p\n"); printf("\\&"); for(c=0; c=0) { tohcol(c); drawvert(lf, i, c, lwid); } if ((form=ctype(i,c))!='s') printf("\\h'|\\n(%du'", (form=='a'&&lused[c]==0)?c+CMID:c+CLEFT); s= table[nl][c].col; fn = font[stynum[i]][c]; size = csize[stynum[i]][c]; if (*size==0)size=0; switch(ct=ctype(i, c)) { case 'n': case 'a': if (table[nl][c].rcol) { if (lused[c]) /*Zero field width*/ { printf("%c%c",F1,F2); puttext(table[nl][c].col,fn,size,nl,c); printf("%c",F1); } s= table[nl][c].rcol; form=1; break; } case 'c': form=3; break; case 'r': form=2; break; case 'l': form=1; break; case '-': case '=': makeline(i,c,ct); continue; default: continue; } if (realsplit ? rused[c]: used[c]) /*Zero field width*/ ; else continue; /* form: 1 left, 2 right, 3 center adjust */ if (ifline(s)) { makeline(i,c,ifline(s)); continue; } printf("%c", F1); if (form!= 1) printf("%c", F2); if (vspen(s)) vspf=1; else puttext(s, fn, size, nl,c); if (form !=2) printf("%c", F2); printf("%c", F1); /* if lines need to be split for gcos here is the place for a backslash */ } printf("\n"); if (allh(i)) printf(".vs\n"); if (watchout) funnies(i,nl); if (vspf) { for(c=0; c=0) if (vspen(table[ip][icol].col)) { printf("\\v'-(\\n(\\*(#du-\\n(^%cu", icol+'a'); if (cmidx) printf("-((\\n(#-u-\\n(^%cu)/2u)", icol+'a'); printf("'"); } printf("%s",s); if (ip>=0) if (vspen(table[ip][icol].col)) { printf("\\v'(\\n(\\*(#du-\\n(^%cu", icol+'a'); if (cmidx) printf("-((\\n(#-u-\\n(^%cu)/2u)", icol+'a'); printf("'"); } if (*fn>0) putfont("P"); if (size!=0) putsize("0"); } else watchout=1; } funnies( stl, lin) { /* write out funny diverted things */ int c, s; char *fn; printf(".mk ##\n"); /* rmember current vertical position */ printf(".nr %d \\n(##\n", S1); /* bottom position */ for(c=0; c0 && vspen(table[prev(stl)][c].col)) { printf(".sp |\\n(^%cu\n", 'a'+c); if (ctop[stynum[stl]][c]==0) { printf(".nr %d \\n(#-u-\\n(^%c-\\n(%c|+1v\n",TMP, 'a'+c, s); printf(".if \\n(%d>0 .sp \\n(%du/2u\n", TMP, TMP); } } printf(".%c+\n",s); printf(".in -\\n(%du\n", SIND); if (*fn>0) putfont("P"); printf(".mk %d\n", S2); printf(".if \\n(%d>\\n(%d .nr %d \\n(%d\n", S2, S1, S1, S2); } printf(".sp |\\n(%du\n", S1); } putfont(fn) char *fn; { if (fn && *fn) printf( fn[1] ? "\\f(%.2s" : "\\f%.2s", fn); } putsize(s) char *s; { if (s && *s) printf("\\s%s",s); } if (ctop[stynum[stl]][c]==0) { printf(".nr %d \\n(#-u-\\n(^%c-\\n(%c|+1v\n",TMP, 'a'+c, s); printf(".if \\n(%d>0 .sp \\n(%du/2u\n", TMP, TMP); } } printf(".%c+\n",s); printf(".in -\\n(%du\n", SIND); if (*fn# include "tbl.c" yetmore() { int icol, ch; while (gets1(cstore=cspace)) { if (prefix(".TE", cstore)) break; if (cstore[0] == '.' && letter(cstore[1])) { puts(cstore); continue; } instead[0]=fullbot[0]=0; if (cstore[1]==0) switch(cstore[0]) { case '_': fullbot[0]= '-'; putline(nlin-1,0); continue; case '=': fullbot[0]= '='; putline(nlin-1, 0); continue; } for (icol = 0; icol =MAXVEC) error("Too many characters in table"); spvecs[spcount++]= pp = calloc(MAXCHS+200,1); if (pp== -1) error("no space for characters"); return(pp); } # define MAXPC 50 char *thisvec; int tpcount -1; char *tpvecs[MAXPC]; alocv(n) { int *tp; if (tpcount<0 || thisvec+n > tpvecs[tpcount]+MAXCHS) { tpcount++; if (tpvecs[tpcount]==0) { tpvecs[tpcount] = calloc(MAXCHS,1); } thisvec = tpvecs[tpcount]; if (thisvec == -1) error("no space for vectors"); } tp=thisvec; thisvec=+n; return(tp); } release() { extern char *exstore; /* give back unwanted space in some vectors */ spcount=0; tpcount= -1; exstore=0; } ("no space for characters"); return(pp); } # define MAXPC 50 char *thisvec; int tpcount -1; char *tpvecs[MAXPC]; alocv(n) { int *tp; if (tpcount<0 || thisvec+n > tpvecs[tpcount]+MAXCHS) { tpcount++; if (tpvecs[tpcount]==0) { tpvecs[tpcount] = calloc(MAXCHS,# include "tbl.c" choochar() { /* choose funny characters to delimit fields */ int had[128], ilin,icol, k; char *s; for(icol=0; icol<128; icol++) had[icol]=0; F1 = F2 = 0; for(ilin=0;ilin= 128 || s<0); } st funny character */ for( s="\002\003\005\006\007!%&#/?,:;<=>@`^~_{}+-*ABCDEFGHIJKMNOPQRSTUVWXYZabcdefgjkoqrstwxyz"; *s; s++) { if (had[*s]==0) { F1= *s; had[F1]=1; break; } } /* choose second funny character */ for( s="\002\003\005\006\007:_~^`@;,<=>#%&!/?{}+-*ABCDEFGHIJKMNOPQRSTUVWXZabcdefgjkoqrstuwxyz"; *s; s++) { if (had[*s]==0) { F2= *s; break; } } if (F1==0 || F2==0) error("couldn't find characters to use for delimiters"); return; } point(s# include "tbl.c" error(s) char *s; { printf(2, "\n%s: line %d: %s\n", ifile, iline, s); # ifdef unix printf(2, "tbl quits\n"); cexit(1); # endif # ifdef gcos printf(2, "run terminated due to error condition detected by tbl preprocessor\n"); cexit(0); # endif } gets1(s) char *s; { char *p; iline++; p=gets(s); while (*s) s++; s--; if (*s == '\\') gets1(s); return(p); } # define BACKMAX 500 char backup[BACKMAX]; char *backp backup; un1getc(c, f) { if (c=='\n') iline--; *backp++ = c; if (backp >= backup+BACKMAX) error("too much backup"); } get1char() { int c; if (backp>backup) c = *--backp; else c=getchar(); if (c== '\n') iline++; return(c); } ifdef gcos printf(2, "run terminated due to error condition detected by tbl preprocessor\n"); cexit(0); # endif } gets1(s) char *s; { char *p; iline++; p=gets(s); while (*s) s++; s--; if (*s == '\\') gets1(s); return(p); } # define BACKMAX 500 char backup[BACKMAX]; char *backp backup; un1getc(c, f) { if (c=='\n') iline--; *backp++ = c; if (backp >= backu# include "tbl.c" savefill() { /* remembers the status of fill mode in nr 45 (SF) */ /* nr SF = 0 means no fill, 1 means fill */ printf(".nr %d \\n(.u\n", SF); printf(".nf\n"); } rstofill() { printf(".if \\n(%d>0 .fi\n", SF); } endoff() { int i; for(i=0; i= backu# include "tbl.c" gettext(sp, ilin,icol, fn, sz) char *sp, *fn, *sz; { /* get a section of text */ char line[256]; printf(".br\n"); printf(".di %c+\n", texname); if (textflg==0) { printf(".nr %d \\n(.lu\n", TMP); /* remember old line length */ textflg=1; } rstofill(); if (fn && *fn) printf(".ft %s\n", fn); if (sz && *sz) printf(".ps %s\n.vs \\n(.s+2\n",sz); if (cll[icol][0]) printf(".ll %sn\n", cll[icol]); else printf(".ll \\n(%du*%du/%du\n",TMP,ctspan(ilin,icol),ncol+1); while (gets1(line)) { if (line[0]=='T' && line[1]=='}' && line[2]== tab) break; if (match("T}", line)) break; printf("%s\n", line); } if (fn && *fn) printf(".ft P\n"); if (sz && *sz) printf(".br\n.ps\n.vs\n"); printf(".br\n"); printf(".di\n"); printf(".nr %c| \\n(dn\n", texname); printf(".nr %c- \\n(dl\n", texname); /* copy remainder of line */ if (line[2]) tcopy (sp, line+3); else *sp=0; return(texname++); } untext() { printf(".nf\n"); printf(".ll \\n(%du\n", TMP); } ,TMP,ctspan(ilin,icol),ncol+1); while (gets1(line)) { if (# include "tbl.c" /* determine local environment for intersections */ interv(i,c) { int ku, kl; if (c>=ncol) { if (dboxflg) { if (i==0) return(BOT); if (i>=nlin-1) return(TOP); return(THRU); } return(0); } ku = i>0 ? lefdata(i-1,c) : 0; if (i+1 >= nlin) kl=0; else kl = lefdata(allh(i) ? i+1 : i, c); if (ku==2 && kl==2) return(THRU); if (ku ==2) return(TOP); if (kl==BOT) return(2); return(0); } interh(i,c) { int kl, kr; if (fullbot[i]== '=' || (dboxflg && (i==0 || i>= nlin-1))) { if (c==ncol) return(LEFT); if (c==0) return(RIGHT); return(THRU); } if (i>=nlin) return(0); kl = c>0 ? thish (i,c-1) : 0; if (kl<=1 && i>0 && allh(up1(i))) kl = c>0 ? thish(up1(i),c-1) : 0; kr = thish(i,c); if (kr<=1 && i>0 && allh(up1(i))) kr = c>0 ? thish(up1(i), c) : 0; if (kl== '=' && kr == '=') return(THRU); if (kl== '=') return(LEFT); if (kr== '=') return(RIGHT); return(0); } up1(i) { i--; while (instead[i] && i>0) i--; return(i); } fullbot[i]== '=' || (dboxflg && (i==0 || i>= nlin-1))) { if (c==ncol# include "tbl.c" maknew(str) char *str; { /* make two numerical fields */ int dpoint, c; char *p, *q, *ba; p = str; for (ba= 0; c = *str; str++) if (c == '\\' && *(str+1)== '&') ba=str; str=p; if (ba==0) { for (dpoint=0; *str; str++) if (*str=='.' && (str>p && digit(*(str-1)) || digit(*(str+1)))) dpoint=str; if (!dpoint && *(str-1)== '$') return(0); if (dpoint==0) for(; str>p; str--) { if (digit( * (str-1) ) ) break; } if (!dpoint && p==str) /* not numerical, don't split */ return(0); if (dpoint) str=dpoint; } else str = ba; p =str; if (exstore ==0 || exstore >exlim) { exstore = chspace(); exlim= exstore+MAXCHS; } q = exstore; while (*exstore++ = *str++); *p = 0; return(q); } (*str=='.' && (str>p && digit(*(str-1)) || digit(*(str+1)))) dpoint=str; if (!dpoint && *(str-1)== '$') return(0); if (dpoint==0) for(; str>p; str--) { if (digit( * (str-1) ) ) break; } if (!dpoint && p==str) /* not match (s1, s2) char *s1, *s2; { while (*s1 == *s2) if (*s1++ == '\0') return(1); else s2++; return(0); } prefix(small, big) char *small, *big; { int c; while ((c= *small++) == *big++) if (c==0) return(1); return(c==0); } letter (ch) { if (ch >= 'a' && ch <= 'z') return(1); if (ch >= 'A' && ch <= 'Z') return(1); return(0); } numb(str) char *str; { /* convert to integer */ int k; for (k=0; *str >= '0' && *str <= '9'; str++) k = k*10 + *str - '0'; return(k); } digit(x) { return(x>= '0' && x<= '9'); } max(a,b) { return( a>b ? a : b); } index (s,c) char *s; { int k; for(k=0; s[k]; k++) if (s[k]==c) return(k); return(-1); } tcopy (s,t) char *s, *t; { while (*s++ = *t++); } 0) return(1); return(c==0); } letter (ch) { if (ch >= 'a' && ch <= 'z') return(1); if (ch >= 'A' && ch <= 'Z') return(1); return(0); } numb(str) char *str; { /* convert to integer */ int k; for (k=0; *str >= '0' && *str <= '9'; str++) k = k*10 + *str - '0'; return(k); } digit(x) { retu# include "tbl.c" ctype(il, ic) { if (instead[il]) return(0); if (fullbot[il]) return(0); il = stynum[il]; return(style[il][ic]); } min(a,b) { return(a0 && thish(i,c-1) == type)return; for(cr=c; cr < ncol && (ctype(i,cr)=='s'||type==thish(i,cr)); cr++); drawline(i, c, cr-1, lintype,0); } fullwide(i, lintype) { int cr, cl; printf(".vs 2p\n"); cr= 0; while (cr0 && vspand(i-1,cl)) cl++; for(cr=cl; cr0 && vspand(i-1,cr)) break; if (cl1) { switch(interv(i,cl)) { case TOP: exhl = ln==0 ? "1p" : "-1p"; break; case BOT: exhl = ln==1 ? "1p" : "-1p"; break; case THRU: exhl = "-1p"; break; } if (exhl[0]) printf("\\h'%s'", exhl); } if (lcount>1) { switch(interv(i,cr+1)) { case TOP: exhr = ln==0 ? "-1p" : "+1p"; break; case BOT: exhr = ln==1 ? "-1p" : "+1p"; break; case THRU: exhr = "-1p"; break; } } if (cr+1>=ncol) printf("\\l'|\\n(TWu%s\\(ul'", exhr); else printf("\\l'(|\\n(%du+|\\n(%du)/2u%s\\(ul'", cr+CRIGHT, cr+1+CLEFT, exhr); } if (oldpos!=0) printf("\\v'%dp'", -oldpos); if (!nodata) printf("\\v'+.5m'"); } getstop() { int i,c,k,junk, stopp; stopp=1; for(i=0; i=0 && linestop[k]==0) linestop[k]= ++stopp; } if (boxflg || allflg || dboxflg) linestop[0]=1; } left(i,c, lwidp) int *lwidp; { int kind, li; /* returns -1 if no line to left */ /* returns number of line where it starts */ /* stores into lwid the kind of line */ *lwidp=0; kind = lefdata(i,c); if (kind==0) return(-1); if (i+1=0 && lefdata(i,c)==kind) i=prev(li=i); if (prev(li)== -1) li=0; *lwidp=kind; return(li); } lefdata(i,c) { int ck; if (i>=nlin) i=nlin-1; if (ctype(i,c) == 's') { for(ck=c; ctype(i,ck)=='s'; ck--); if (thish(i,ck)==0) return(0); } i =stynum[i]; i = lefline[i][c]; if (i>0) return(i); if (dboxflg && c==0) return(2); if (allflg)return(1); if (boxflg && c==0) return(1); return(0); } next(i) { while (i+1 =0 && (fullbot[i] || instead[i])) ; return(i); } (prev(li)== -1) li=0; *lwidp=kind; return(li); } lefdata(i,c) { int ck; if (i>=nlin) i=nlin-1; if (ctype(i,c) == 's') { for(ck=c; ctype(i,ck)=='s'; ck--); if (thish(i,ck)==0) return(0); } i =stynum[i]; i = lefline[i][c]; if (i>0) return(i); if (dboxflg && c==0) return(2); if (allflg)return(1); if (boxflg && c==0) return(1); return(0); }# include "tbl.c" drawvert(start,end, c, lwid) { char *exb1, *exb2, *ext1, *ext2; int sl, ln, tp, pos; tp =exb1 =exb2 =ext1 = ext2 = 0; end++; while (instead[end]) end++; for(ln=0; ln0) k = midbcol(i, c-1); return(k); } midbcol(i,c) { int ct; while ( (ct=ctype(i,c)) == 's') c--; if (ct=='-' || ct == '=') return(ct); if (ct=barent(table[i][c].col)) return(ct); return(0); } barent(s) char *s; { if (s==0) return (1); if (s[1]!= 0) return(0); switch(s[0]) { case '_': return('-'); case '=': return('='); } return(0); } stop[start]+'a'-1); if (ext1) printf("+%s",ext1); if (ext2) printf("-%s", ext2); printf("'"); } } midbar(i,c) { int k; k = midbcol(i,c); if (k==0 && c>0) k = midbcol(i, c-1); return(k); } midbcol(i,c) { int ct; while"\001 ", /*space*/ "\001!", /*!*/ "\001\"", /*"*/ "\001#", /*#*/ "\001$", /*$*/ "\001%", /*%*/ "\001&", /*&*/ "\001'", /*' close*/ "\001(", /*(*/ "\001)", /*)*/ "\001*", /***/ "\001+", /*+*/ "\001,", /*,*/ "\001-", /*- hyphen*/ "\001.", /*.*/ "\001/", /*/*/ "\2010", /*0*/ "\2011", /*1*/ "\2012", /*2*/ "\2013", /*3*/ "\2014", /*4*/ "\2015", /*5*/ "\2016", /*6*/ "\2017", /*7*/ "\2018", /*8*/ "\2019", /*9*/ "\001:", /*:*/ "\001;", /*;*/ "\001<", /*<*/ "\001=", /*=*/ "\001>", /*>*/ "\001?", /*?*/ "\001@", /*@*/ "\201A", /*A*/ "\201B", /*B*/ "\201C", /*C*/ "\201D", /*D*/ "\201E", /*E*/ "\201F", /*F*/ "\201G", /*G*/ "\201H", /*H*/ "\201I", /*I*/ "\201J", /*J*/ "\201K", /*K*/ "\201L", /*L*/ "\201M", /*M*/ "\201N", /*N*/ "\201O", /*O*/ "\201P", /*P*/ "\201Q", /*Q*/ "\201R", /*R*/ "\201S", /*S*/ "\201T", /*T*/ "\201U", /*U*/ "\201V", /*V*/ "\201W", /*W*/ "\201X", /*X*/ "\201Y", /*Y*/ "\201Z", /*Z*/ "\001[", /*[*/ "\001\\", /*\*/ "\001]", /*]*/ "\001^", /*^*/ "\001_", /*_ dash*/ "\001`", /*` open*/ "\201a", /*a*/ "\201b", /*b*/ "\201c", /*c*/ "\201d", /*d*/ "\201e", /*e*/ "\201f", /*f*/ "\201g", /*g*/ "\201h", /*h*/ "\201i", /*i*/ "\201j", /*j*/ "\201k", /*k*/ "\201l", /*l*/ "\201m", /*m*/ "\201n", /*n*/ "\201o", /*o*/ "\201p", /*p*/ "\201q", /*q*/ "\201r", /*r*/ "\201s", /*s*/ "\201t", /*t*/ "\201u", /*u*/ "\201v", /*v*/ "\201w", /*w*/ "\201x", /*x*/ "\201y", /*y*/ "\201z", /*z*/ "\001{", /*{*/ "\001|", /*|*/ "\001}", /*}*/ "\001~", /*~*/ "\000\0", /*narrow sp*/ "\001-", /*hyphen*/ "\001o\b+", /*bullet*/ "\002\[]", /*square*/ "\001-", /*3/4 em*/ "\001_", /*rule*/ "\000\0", /*1/4*/ "\000\0", /*1/2*/ "\000\0", /*3/4*/ "\001-", /*minus*/ "\202fi", /*fi*/ "\202fl", /*fl*/ "\202ff", /*ff*/ "\203ffi", /*ffi*/ "\203ffl", /*ffl*/ "\000\0", /*degree*/ "\000\0", /*dagger*/ "\000\0", /*section*/ "\001'", /*foot mark*/ "\001'", /*acute accent*/ "\001`", /*grave accent*/ "\001_", /*underrule*/ "\001/", /*slash (longer)*/ "\000\0", /*half narrow space*/ "\001 ", /*unpaddable space*/ "\001\241c\202(\241", /*alpha*/ "\001\200B\242\302\|\202\342", /*beta*/ "\001\200)\201/\241", /*gamma*/ "\001\200o\342<\302", /*delta*/ "\001<\b-", /*epsilon*/ "\001\200c\201\301,\241\343<\302", /*zeta*/ "\001\200n\202\302|\242\342", /*eta*/ "\001O\b-", /*theta*/ "\001i", /*iota*/ "\001k", /*kappa*/ "\001\200\\\304\241'\301\241'\345\202", /*lambda*/ "\001\200u\242,\202", /*mu*/ "\001\241(\203/\242", /*nu*/ "\001\200c\201\301,\241\343c\241\301`\201\301", /*xi*/ "\001o", /*omicron*/ "\001\341-\303\"\301\"\343", /*pi*/ "\001\200o\242\302|\342\202", /*rho*/ "\001\200o\301\202~\341\242", /*sigma*/ "\001\200t\301\202~\243~\201\341", /*tau*/ "\001v", /*upsilon*/ "\001o\b/", /*phi*/ "\001x", /*chi*/ "\001\200/-\302\202'\244'\202\342", /*psi*/ "\001\241u\203u\242", /*omega*/ "\001\242|\202\343-\303\202`\242", /*Gamma*/ "\001\242/\303-\204-\343\\\242", /*Delta*/ "\001O\b=", /*Theta*/ "\001\242/\204\\\242", /*Lambda*/ "\000\0", /*Xi*/ "\001\242[]\204[]\242\343-\303", /*Pi*/ "\001\200>\302-\345-\303", /*Sigma*/ "\000\0", /**/ "\001Y", /*Upsilon*/ "\001o\b[\b]", /*Phi*/ "\001\200[]-\302\202'\244`\202\342", /*Psi*/ "\001\200O\302\241-\202-\241\342", /*Omega*/ "\000\0", /*square root*/ "\000\0", /*terminal sigma*/ "\000\0", /*root en*/ "\001>\b_", /*>=*/ "\001<\b_", /*<=*/ "\001=\b_", /*identically equal*/ "\001-", /*equation minus*/ "\001=\b~", /*approx =*/ "\000\0", /*approximates*/ "\001=\b/", /*not equal*/ "\002->", /*right arrow*/ "\002<-", /*left arrow*/ "\001|\b^", /*up arrow*/ "\000\0", /*down arrow*/ "\001=", /*equation equal*/ "\001x", /*multiply*/ "\001/", /*divide*/ "\001+\b_", /*plus-minus*/ "\001U", /*cup (union)*/ "\000\0", /*cap (intersection)*/ "\000\0", /*subset of*/ "\000\0", /*superset of*/ "\000\0", /*improper subset*/ "\000\0", /* improper superset*/ "\002oo", /*infinity*/ "\001\200o\201\301`\241\341`\241\341`\201\301", /*partial derivative*/ "\001\242\\\343-\204-\303/\242", /*gradient*/ "\001\200-\202\341,\301\242", /*not*/ "\001\200|'\202`\243\306'\241`\202\346", /*integral sign*/ "\000\0", /*proportional to*/ "\000\0", /*empty set*/ "\000\0", /*member of*/ "\001+", /*equation plus*/ "\001r\bO", /*registered*/ "\001c\bO", /*copyright*/ "\001|", /*box rule */ "\001c\b/", /*cent sign*/ "\000\0", /*dbl dagger*/ "\000\0", /*right hand*/ "\001*", /*left hand*/ "\001*", /*math * */ "\000\0", /*bell system sign*/ "\001|", /*or (was star)*/ "\001O", /*circle*/ "\001|", /*left top (of big curly)*/ "\001|", /*left bottom*/ "\001|", /*right top*/ "\001|", /*right bot*/ "\001|", /*left center of big curly bracket*/ "\001|", /*right center of big curly bracket*/ "\001|", /*bold vertical*/ "\001|", /*left floor (left bot of big sq bract)*/ "\001|", /*right floor (rb of ")*/ "\001|", /*left ceiling (lt of ")*/ "\001|"}; /*right ceiling (rt of ")*/ /*left hand*/ "\001*", /*math * */ "\000\0", /*bell system sign*/ "\001|", /*or (was star)*/ "\001O", /*circle*/ "\001|", /*left top (of big curly)*/ "\001|", /*left bottom*/ "\001|", /*right top*/ "\001|", /*right bot*/ "\001|", /*left center of #define INCH 240 /* DASI300 nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "\007", /*twrest*/ "\007", /*twnl*/ "\015\n", /*hlr*/ "", /*hlf*/ "", /*flr*/ "\013", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\006", /*plotoff*/ "\033\006", /*up*/ "\013", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*#define INCH 240 /* DASI300S nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "\033\006", /*twrest*/ "\033\006", /*twnl*/ "\015\n", /*hlr*/ "\033H", /*hlf*/ "\033h", /*flr*/ "\032", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\006", /*plotoff*/ "\033\006", /*up*/ "\032", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char#define INCH 240 /* DASI300 nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "\007", /*twrest*/ "\007", /*twnl*/ "\015\n", /*hlr*/ "", /*hlf*/ "", /*flr*/ "\013", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\006", /*plotoff*/ "\033\006", /*up*/ "\013", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*#define INCH 240 /* DASI300S nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "\033\006", /*twrest*/ "\033\006", /*twnl*/ "\015\n", /*hlr*/ "\033H", /*hlf*/ "\033h", /*flr*/ "\032", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\006", /*plotoff*/ "\033\006", /*up*/ "\032", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char#define INCH 240 /* TTY M37 nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0, /*Hor*/ INCH/10, /*Vert*/ INCH/12, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "", /*twrest*/ "", /*twnl*/ "\n", /*hlr*/ "\0338", /*hlf*/ "\0339", /*flr*/ "\0337", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "", /*plotoff*/ "", /*up*/ "", /*down*/ "", /*right*/ "", /*left*/ "", /*codetab*/ "\001 ", /*space*/ "\001!", /*!*/ "\001\"", /*"*/ "\001#", /*#*/ "\001$", /*$*/ "\001%", /*%*/ "\001&", /*&*/ "\001'", /*' close*/ "\001(", /*(*/ "\001)", /*)*/ "\001*", /***/ "\001+", /*+*/ "\001,", /*,*/ "\001-", /*- hyphen*/ "\001.", /*.*/ "\001/", /*/*/ "\2010", /*0*/ "\2011", /*1*/ "\2012", /*2*/ "\2013", /*3*/ "\2014", /*4*/ "\2015", /*5*/ "\2016", /*6*/ "\2017", /*7*/ "\2018", /*8*/ "\2019", /*9*/ "\001:", /*:*/ "\001;", /*;*/ "\001<", /*<*/ "\001=", /*=*/ "\001>", /*>*/ "\001?", /*?*/ "\001@", /*@*/ "\201A", /*A*/ "\201B", /*B*/ "\201C", /*C*/ "\201D", /*D*/ "\201E", /*E*/ "\201F", /*F*/ "\201G", /*G*/ "\201H", /*H*/ "\201I", /*I*/ "\201J", /*J*/ "\201K", /*K*/ "\201L", /*L*/ "\201M", /*M*/ "\201N", /*N*/ "\201O", /*O*/ "\201P", /*P*/ "\201Q", /*Q*/ "\201R", /*R*/ "\201S", /*S*/ "\201T", /*T*/ "\201U", /*U*/ "\201V", /*V*/ "\201W", /*W*/ "\201X", /*X*/ "\201Y", /*Y*/ "\201Z", /*Z*/ "\001[", /*[*/ "\001\\", /*\*/ "\001]", /*]*/ "\001^", /*^*/ "\001_", /*_ dash*/ "\001`", /*` open*/ "\201a", /*a*/ "\201b", /*b*/ "\201c", /*c*/ "\201d", /*d*/ "\201e", /*e*/ "\201f", /*f*/ "\201g", /*g*/ "\201h", /*h*/ "\201i", /*i*/ "\201j", /*j*/ "\201k", /*k*/ "\201l", /*l*/ "\201m", /*m*/ "\201n", /*n*/ "\201o", /*o*/ "\201p", /*p*/ "\201q", /*q*/ "\201r", /*r*/ "\201s", /*s*/ "\201t", /*t*/ "\201u", /*u*/ "\201v", /*v*/ "\201w", /*w*/ "\201x", /*x*/ "\201y", /*y*/ "\201z", /*z*/ "\001{", /*{*/ "\001|", /*|*/ "\001}", /*}*/ "\001~", /*~*/ "\000\0", /*narrow sp*/ "\001-", /*hyphen*/ "\001o\b+", /*bullet*/ "\002\[]", /*square*/ "\001-", /*3/4 em*/ "\001_", /*rule*/ "\0031/4", /*1/4*/ "\0031/2", /*1/2*/ "\0033/4", /*3/4*/ "\001-", /*minus*/ "\202fi", /*fi*/ "\202fl", /*fl*/ "\202ff", /*ff*/ "\203ffi", /*ffi*/ "\203ffl", /*ffl*/ "\000\0", /*degree*/ "\000\0", /*dagger*/ "\000\0", /*section*/ "\001'", /*foot mark*/ "\001'", /*acute accent*/ "\001`", /*grave accent*/ "\001_", /*underrule*/ "\001/", /*slash (longer)*/ "\000\0", /*half narrow space*/ "\001 ", /*unpaddable space*/ "\201\016A\017", /*alpha*/ "\201\016B\017", /*beta*/ "\201\016\\\017", /*gamma*/ "\201\016D\017", /*delta*/ "\201\016S\017", /*epsilon*/ "\201\016Q\017", /*zeta*/ "\201\016N\017", /*eta*/ "\201\016O\017", /*theta*/ "\201i", /*iota*/ "\201k", /*kappa*/ "\201\016L\017", /*lambda*/ "\201\016M\017", /*mu*/ "\201\016@\017", /*nu*/ "\201\016X\017", /*xi*/ "\201o", /*omicron*/ "\201\016J\017", /*pi*/ "\201\016K\017", /*rho*/ "\201\016Y\017", /*sigma*/ "\201\016I\017", /*tau*/ "\201v", /*upsilon*/ "\201\016U\017", /*phi*/ "\201x", /*chi*/ "\201\016V\017", /*psi*/ "\201\016C\017", /*omega*/ "\201\016G\017", /*Gamma*/ "\201\016W\017", /*Delta*/ "\201\016T\017", /*Theta*/ "\201\016E\017", /*Lambda*/ "\000\0", /*Xi*/ "\201\016P\017", /*Pi*/ "\201\016R\017", /*Sigma*/ "\000\0", /**/ "\201Y", /*Upsilon*/ "\201\016F\017", /*Phi*/ "\201\016H\017", /*Psi*/ "\201\016Z\017", /*Omega*/ "\000\0", /*square root*/ "\000\0", /*terminal sigma*/ "\000\0", /*root en*/ "\001>\b_", /*>=*/ "\001<\b_", /*<=*/ "\001=\b_", /*identically equal*/ "\001-", /*equation minus*/ "\001=\b~", /*approx =*/ "\001\0339~\0338", /*approximates*/ "\001=\b/", /*not equal*/ "\002->", /*right arrow*/ "\002<-", /*left arrow*/ "\001|\b^", /*up arrow*/ "\000\0", /*down arrow*/ "\001=", /*equation equal*/ "\001x", /*multiply*/ "\001/", /*divide*/ "\001+\b_", /*plus-minus*/ "\001U", /*cup (union)*/ "\000\0", /*cap (intersection)*/ "\000\0", /*subset of*/ "\000\0", /*superset of*/ "\000\0", /*improper subset*/ "\000\0", /* improper superset*/ "\002oo", /*infinity*/ "\001\016]\017", /*partial derivative*/ "\001\016[\017", /*gradient*/ "\001\016_\017", /*not*/ "\001\016^\017", /*integral sign*/ "\000\0", /*proportional to*/ "\000\0", /*empty set*/ "\000\0", /*member of*/ "\001+", /*equation plus*/ "\001\0338r\0339", /*registered*/ "\001\0338c\0339", /*copyright*/ "\001|", /*box rule */ "\001c\b/", /*cent sign*/ "\000\0", /*dbl dagger*/ "\000\0", /*right hand*/ "\001*", /*left hand*/ "\001*", /*math * */ "\000\0", /*bell system sign*/ "\001|", /*or (was star)*/ "\001O", /*circle*/ "\001|", /*left top (of big curly)*/ "\001|", /*left bottom*/ "\001|", /*right top*/ "\001|", /*right bot*/ "\001|", /*left center of big curly bracket*/ "\001|", /*right center of big curly bracket*/ "\001|", /*bold vertical*/ "\001|", /*left floor (left bot of big sq bract)*/ "\001|", /*right floor (rb of ")*/ "\001|", /*left ceiling (lt of ")*/ "\001|"}; /*right ceiling (rt of ")*/ /*left hand*/ "\001*", /*math * */ "\000\0", /*bell system sign*/ "\001|", /*or (was star)*/ "\001O", /*circle*/ "\001|", /*left top (of big curly)*/ "\001|", /*left bottom*/ "\001|", /*right top*/ "\001|", /*right bot*/ "\001|", /*left center of big curly bracket*/ "\001|", /*right center of big curly brack#define INCH 240 /* DASI450 nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/12, /*Em*/ INCH/12, /*Halfline*/ INCH/12, /*Adj*/ INCH/12, /*twinit*/ "\0334\033\037\013", /*twrest*/ "\0334\033\037\015", /*twnl*/ "\015\n", /*hlr*/ "\033D", /*hlf*/ "\033U", /*flr*/ "\033\n", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\0333", /*plotoff*/ "\0334", /*up*/ "\033\n", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*#define INCH 240 /* DASI450 nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "\0334", /*twrest*/ "\0334", /*twnl*/ "\015\n", /*hlr*/ "\033D", /*hlf*/ "\033U", /*flr*/ "\033\n", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\0333", /*plotoff*/ "\0334", /*up*/ "\033\n", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" wn; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*#define INCH 240 /* DASI300S nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "\0334", /*twrest*/ "\0334", /*twnl*/ "\015\n", /*hlr*/ "\033D", /*hlf*/ "\033U", /*flr*/ "\033\n", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "\0333", /*plotoff*/ "\0334", /*up*/ "\033\n", /*down*/ "\n", /*right*/ " ", /*left*/ "\b", /*codetab*/ #include "code.300" wn; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0177420, /*Hor*/ INCH/60, /*Vert*/ INCH/48, /*Newline*/ INCH/6, /*Char#define INCH 240 /* TTY M37 nroff driving tables width and code tables */ struct { int bset; int breset; int Hor; int Vert; int Newline; int Char; int Em; int Halfline; int Adj; char *twinit; char *twrest; char *twnl; char *hlr; char *hlf; char *flr; char *bdon; char *bdoff; char *ploton; char *plotoff; char *up; char *down; char *right; char *left; char *codetab[256-32]; int zzz; } t { /*bset*/ 0, /*breset*/ 0, /*Hor*/ INCH/10, /*Vert*/ INCH/6, /*Newline*/ INCH/6, /*Char*/ INCH/10, /*Em*/ INCH/10, /*Halfline*/ INCH/12, /*Adj*/ INCH/10, /*twinit*/ "", /*twrest*/ "", /*twnl*/ "\n", /*hlr*/ "", /*hlf*/ "", /*flr*/ "", /*bdon*/ "", /*bdoff*/ "", /*ploton*/ "", /*plotoff*/ "", /*up*/ "", /*down*/ "", /*right*/ "", /*left*/ "", /*codetab*/ "\001 ", /*space*/ "\001!", /*!*/ "\001\"", /*"*/ "\001#", /*#*/ "\001$", /*$*/ "\001%", /*%*/ "\001&", /*&*/ "\001'", /*' close*/ "\001(", /*(*/ "\001)", /*)*/ "\001*", /***/ "\001+", /*+*/ "\001,", /*,*/ "\001-", /*- hyphen*/ "\001.", /*.*/ "\001/", /*/*/ "\2010", /*0*/ "\2011", /*1*/ "\2012", /*2*/ "\2013", /*3*/ "\2014", /*4*/ "\2015", /*5*/ "\2016", /*6*/ "\2017", /*7*/ "\2018", /*8*/ "\2019", /*9*/ "\001:", /*:*/ "\001;", /*;*/ "\001<", /*<*/ "\001=", /*=*/ "\001>", /*>*/ "\001?", /*?*/ "\001@", /*@*/ "\201A", /*A*/ "\201B", /*B*/ "\201C", /*C*/ "\201D", /*D*/ "\201E", /*E*/ "\201F", /*F*/ "\201G", /*G*/ "\201H", /*H*/ "\201I", /*I*/ "\201J", /*J*/ "\201K", /*K*/ "\201L", /*L*/ "\201M", /*M*/ "\201N", /*N*/ "\201O", /*O*/ "\201P", /*P*/ "\201Q", /*Q*/ "\201R", /*R*/ "\201S", /*S*/ "\201T", /*T*/ "\201U", /*U*/ "\201V", /*V*/ "\201W", /*W*/ "\201X", /*X*/ "\201Y", /*Y*/ "\201Z", /*Z*/ "\001[", /*[*/ "\001\\", /*\*/ "\001]", /*]*/ "\001^", /*^*/ "\001_", /*_ dash*/ "\001`", /*` open*/ "\201a", /*a*/ "\201b", /*b*/ "\201c", /*c*/ "\201d", /*d*/ "\201e", /*e*/ "\201f", /*f*/ "\201g", /*g*/ "\201h", /*h*/ "\201i", /*i*/ "\201j", /*j*/ "\201k", /*k*/ "\201l", /*l*/ "\201m", /*m*/ "\201n", /*n*/ "\201o", /*o*/ "\201p", /*p*/ "\201q", /*q*/ "\201r", /*r*/ "\201s", /*s*/ "\201t", /*t*/ "\201u", /*u*/ "\201v", /*v*/ "\201w", /*w*/ "\201x", /*x*/ "\201y", /*y*/ "\201z", /*z*/ "\001{", /*{*/ "\001|", /*|*/ "\001}", /*}*/ "\001~", /*~*/ "\000\0", /*nar sp*/ "\001-", /*hyphen*/ "\001o\b+", /*bullet*/ "\002\[]", /*square*/ "\001-", /*3/4 em*/ "\001_", /*rule*/ "\000\0", /*1/4*/ "\000\0", /*1/2*/ "\000\0", /*3/4*/ "\001-", /*minus*/ "\202fi", /*fi*/ "\202fl", /*fl*/ "\202ff", /*ff*/ "\203ffi", /*ffi*/ "\203ffl", /*ffl*/ "\000\0", /*degree*/ "\000\0", /*dagger*/ "\000\0", /*section*/ "\001'", /*foot mark*/ "\001'", /*acute accent*/ "\001`", /*grave accent*/ "\001_", /*underrule*/ "\001/", /*slash (longer)*/ "\000\0", /*half narrow space*/ "\001 ", /*unpaddable space*/ "\000", /*alpha*/ "\000", /*beta*/ "\000", /*gamma*/ "\000", /*delta*/ "\000", /*epsilon*/ "\000", /*zeta*/ "\000", /*eta*/ "\000", /*theta*/ "\201i", /*iota*/ "\201k", /*kappa*/ "\000", /*lambda*/ "\000", /*mu*/ "\000", /*nu*/ "\000", /*xi*/ "\201o", /*omicron*/ "\000", /*pi*/ "\000", /*rho*/ "\000", /*sigma*/ "\000", /*tau*/ "\201v", /*upsilon*/ "\000", /*phi*/ "\201x", /*chi*/ "\000", /*psi*/ "\000", /*omega*/ "\000", /*Gamma*/ "\000", /*Delta*/ "\000", /*Theta*/ "\000", /*Lambda*/ "\000\0", /*Xi*/ "\000", /*Pi*/ "\000", /*Sigma*/ "\000\0", /**/ "\201Y", /*Upsilon*/ "\000", /*Phi*/ "\000", /*Psi*/ "\000", /*Omega*/ "\000\0", /*square root*/ "\000\0", /*terminal sigma*/ "\000\0", /*root en*/ "\001>\b_", /*>=*/ "\001<\b_", /*<=*/ "\001=\b_", /*identically equal*/ "\001-", /*equation minus*/ "\001=\b~", /*approx =*/ "\000\0", /*approximates*/ "\001=\b/", /*not equal*/ "\002->", /*right arrow*/ "\002<-", /*left arrow*/ "\001|\b^", /*up arrow*/ "\000\0", /*down arrow*/ "\001=", /*equation equal*/ "\001x", /*multiply*/ "\001/", /*divide*/ "\001+\b_", /*plus-minus*/ "\001U", /*cup (union)*/ "\000\0", /*cap (intersection)*/ "\000\0", /*subset of*/ "\000\0", /*superset of*/ "\000\0", /*improper subset*/ "\000\0", /* improper superset*/ "\002oo", /*infinity*/ "\000", /*partial derivative*/ "\000", /*gradient*/ "\000", /*not*/ "\000", /*integral sign*/ "\000\0", /*proportional to*/ "\000\0", /*empty set*/ "\000\0", /*member of*/ "\001+", /*equation plus*/ "\001r\bO", /*registered*/ "\001c\bO", /*copyright*/ "\001|", /*box rule */ "\001c\b/", /*cent sign*/ "\000\0", /*dbl dagger*/ "\000\0", /*right hand*/ "\001*", /*left hand*/ "\001*", /*math * */ "\000\0", /*bell system sign*/ "\001|", /*or (was star)*/ "\001O", /*circle*/ "\001|", /*left top (of big curly)*/ "\001|", /*left bottom*/ "\001|", /*right top*/ "\001|", /*right bot*/ "\001|", /*left center of big curly bracket*/ "\001|", /*right center of big curly bracket*/ "\001|", /*bold vertical*/ "\001|", /*left floor (left bot of big sq bract)*/ "\001|", /*right floor (rb of ")*/ "\001|", /*left ceiling (lt of ")*/ "\001|"}; /*right ceiling (rt of ")*/ /*left hand*/ "\001*", /*math * */ "\000\0", /*bell system sign*/ "\001|", /*or (was star)*/ "\001O", /*circle*/ "\001|", /*left top / / / / UNIX SUPPORT GROUP MODIFICATION 2.36 / / tap1 -- dec-disk lod/dmp .globl _localtime, _end namep = 0 mode = 2 uid = 4; gid = 5 size0 = 7 size1 = 8 time0 = 10. time1 = 12. tapea = 14. dirsiz = 16. mdirent = 496. mov (sp),rnarg mov (sp)+,narg mov $cmr,command incb flu tst (sp)+ cmp narg,$2 bge 1f mov $2,narg br 3f 1: mov (sp)+,r0 mov sp,parg 1: movb (r0)+,r1 beq 3f mov $swtab,r2 2: cmp r1,(r2)+ beq 2f tst (r2)+ bne 2b br useerr 2: jsr pc,*(r2)+ br 1b 3: jsr pc,optap mov $_end,r4 / string pointer jsr pc,setb jmp *command optap: tstb flm bne 2f mov $578.,tapsiz mov $192.,ndirent sys open; tc; 2 br 3f 2: mov $-1,tapsiz mov $mdirent,ndirent cmp command,$cmr beq 2f sys open; mt; 0 br 3f 2: sys open; mt; 1 3: bes 1f mov r0,fio mov ndirent,r1 ash $-3,r1 mov r1,ndentd8 mov ndirent,r1 mul $dirsiz,r1 add $dir,r1 mov r1,edir rts pc 1: jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done setcom: cmp command,$cmr bne useerr  mov (r5)+,command rts r5 noflag: mov (r5)+,r0 beq 1f tstb (r0) beq noflag br useerr 1: rts r5 useerr: jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done swtab: '0; dcof '1; dcof '2; dcof '3; dcof '4; dcof '5; dcof '6; dcof '7; dcof 'c; dcc 'd; dcd 'f; dcf 'i; dci 'm; dcm 'r; dcr 't; dct 'u; dcu 'v; dcv 'w; dcw 'x; dcx 0; 0 dcof: movb r1,tcx movb r1,mtx rts pc dcc: incb flc rts pc dcf: incb flf rts pc dcd: jsr r5,setcom; cmd rts pc dci: incb fli rts pc dcm: incb flm rts pc dcu: incb flu jsr r5,setcom; cmr rts pc dcr: clrb flu jsr r5,setcom; cmr rts pc dct: jsr r5,setcom; cmt rts pc dcv: incb flv rts pc dcw: incb flw rts pc dcx: jsr r5,setcom; cmx rts pc cmd: jsr r5,noflag; flm; flc; flf; 0 cmp narg,$2 bgt 1f jmp useerr 1: jsr pc,rddir jsr r5,gettape; delete jsr pc,wrdir br check cmr: jsr r5,noflag; 0 tstb flc bne 1f tstb flm bne 1f jsr pc,rddir br 2f 1: jsr pc,clrdir 2: jsr pc,getfiles  jsr pc,update br check cmt: jsr r5,noflag; flc; flf; flw; 0 jsr pc,rddir tstb flv beq 1f jsr r5,mesg < mode uid gid tapa size date time name\n\0>; .even 1: jsr r5,gettape; taboc br check1 cmx: jsr r5,noflag; flc; flf; 0 jsr pc,rddir jsr r5,gettape; xtract clr r0 /set condition code to 0 br done check: check1: jsr pc,usage done: jsr r5,mesg ; .even sys exit encode: mov r2,-(sp) mov r4,(r1) mov (r5)+,r2 1: movb (r2),(r4)+ jsr pc,setb tstb (r2)+ bne 1b mov (sp)+,r2 rts r5 decode: mov r2,-(sp) mov r1,-(sp) mov (r1),r1 mov (r5)+,r2 1: movb (r1)+,(r2)+ bne 1b mov (sp)+,r1 mov (sp)+,r2 rts r5 setb: mov r0,-(sp) mov r4,r0 add $513.,r0 cmp r0,sp bhis 2f bic $777,r0 cmp r0,0f beq 1f mov r0,0f sys break; 0:.. bes 2f 1: mov (sp)+,r0 rts pc 2: jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done exit encode: mov r2,-(sp) mov r4,(r1) mov (r5)+,r2 1: movb (r2),(r4)+ jsr pc,setb tstb (r2)+ bne 1b m/ / / / UNIX SUPPORT GROUP MODIFICATION 2.36 / / tap2 -- dec-tape lod/dmp pstr: movb (r1)+,r0 beq 1f jsr pc,putc br pstr 1: rts pc mesg: movb (r5)+,r0 beq 1f jsr pc,putc br mesg 1: inc r5 bic $1,r5 rts r5 putc: movb r0,ch mov $1,r0 sys write; ch; 1 rts pc getc: clr r0 sys read; ch; 1 movb ch,r0 rts pc clrdir: mov $dir,r1 mov ndirent,r2 1: jsr pc,clrent sob r2,1b rts pc clrent: mov r1,-(sp) add $dirsiz,(sp) 1: clr (r1)+ cmp r1,(sp) blo 1b tst (sp)+ rts pc rddir: clr sum jsr pc,clrdir clr r0 jsr pc,rseek jsr pc,tread mov tapeb+510.,r0 beq 1f tstb flm beq 1f mov r0,ndirent 1: mov $dir,r1 mov ndirent,r2 1: bit $7,r2 bne 2f jsr pc,tread mov $tapeb,r3 2: mov r1,-(sp) mov r3,-(sp) mov $32.,r0 clr -(sp) 2: add (r3)+,(sp) sob r0,2b bis (sp),sum tst (sp)+ bne 2f mov (sp),r3 tst (r3) beq 2f mov r3,0f jsr pc,9f .data 9: jsr r5,encode; 0:.. rts pc .text add $32.,r3 mov r1,-(sp) add $dirsiz,(sp) tst (r1)+ / namep 9: mov (r3)+,(r1)+ cmp r1,(sp) blo 9b tst (sp)+ 2: mov (sp)+,r3 add $64.,r3 mov (sp)+,r1 bic $100000,mode(r1) add $dirsiz,r1 sob r2,1b tst sum beq 1f jsr r5,mesg ; .even tstb fli bne 1f clr r0 /set condition code to 0 jmp done 1: jsr pc,bitmap rts pc wrdir: clr r0 jsr pc,wseek tstb flm bne 1f sys open; tboot; 0 bes 3f br 2f 1: sys open; mboot; 0 bes 3f 2: mov r0,r1 sys read; tapeb; 512. mov r1,r0 sys close mov ndirent,tapeb+510. 3: jsr pc,twrite mov $dir,r1 mov ndirent,r2 1: bit $7,r2 bne 2f mov $256.,r0 mov $tapeb,r3 3: clr (r3)+ sob r0,3b mov $tapeb,r3 2: mov r3,-(sp) tst (r1) beq 2f mov r3,0f jsr pc,9f .data 9: jsr r5,decode; 0:.. rts pc .text 2: add $32.,r3 mov r1,-(sp) add $dirsiz,(sp) tst (r1)+ 9: mov (r1)+,(r3)+ cmp r1,(sp) blo 9b tst (sp)+ mov (sp)+,r3 clr -(sp) mov $31.,r0 2: sub (r3)+,(sp) sob r0,2b mov (sp)+,(r3)+ dec r2 bit $7,r2 bne 1b jsr pc,twrite tst r2 bne 1b rts pc tread: mov fio,r0 sys read; tapeb; 512. bes trderr cmp r0,$512. bne trderr 1: inc rseeka rts pc trderr: jsr r5,mesg ; .even tstb fli beq 1f mov $tapeb,r0 2: clr (r0)+ cmp r0,$tapeb+512. blo 2b br 1b 1: mov $12,r0 /set condition code to 12 jmp done twrite: mov fio,r0 sys write; tapeb; 512. bes twrerr cmp r0,$512. bne twrerr inc wseeka rts pc twrerr: jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done rseek: mov r0,rseeka mov r0,0f mov fio,r0 sys 0; 9f .data 9: sys seek; 0:..; 3 .text bes seekerr rts pc wseek: mov r0,-(sp) sub wseeka,r0 bge 1f neg r0 1: cmp r0,$25. / longest write seek ble 1f mov (sp),0f beq 2f dec 0f 2: mov fio,r0 sys 0; 9f .data 9: sys seek; 0:..; 3 .text mov fio,r0 sys read; wseeka; 1 1: mov (sp),wseeka mov (sp)+,0f mov fio,r0 sys 0; 9f .data 9: sys seek; 0:..; 3 .text bes seekerr rts pc seekerr: jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done verify: movb (r5)+,0f inc r5 tstb flw bne 1f tstb flv beq 2f 1: jsr pc,9f .data 9: jsr r5,mesg 0:; .even rts pc .text mov r1,-(sp) mov $name,r1 jsr pc,pstr mov (sp)+,r1 tstb flw beq 1f jsr r5,mesg < \0> jsr pc,getc cmp r0,$'x bne 3f jsr pc,getc clr r0 /set condition code to 0 jmp done 3: cmp r0,$'\n beq 3f cmp r0,$'y bne 4f jsr pc,getc cmp r0,$'\n beq 2f 4: jsr pc,getc cmp r0,$'\n bne 4b br 1b 1: jsr r5,mesg <\n\0> 2: tst (r5)+ 3: rts r5 getfiles: cmp narg,$2 bne 1f mov $".\0,name jsr pc,callout 1: cmp narg,$2 ble 1f dec narg mov *parg,r1 add $2,parg mov $name,r2 2: movb (r1)+,(r2)+ bne 2b jsr pc,callout br 1b 1: rts pc expand: sys open; name; 0 bes fserr mov r0,-(sp) 1: mov (sp),r0 sys read; catlb; 16. bes fserr tst r0 beq 1f tst catlb beq 1b mov $name,r0 mov $catlb+2,r1 cmpb (r1),$'. beq 1b 2: tstb (r0)+ bne 2b dec r0 mov r0,-(sp) cmpb -1(r0),$'/ beq 2f movb $'/,(r0)+ 2: movb (r1)+,(r0)+ bne 2b jsr pc,callout clrb *(sp)+ br 1b 1: mov (sp)+,r0 sys close rts pc fserr: mov $name,r1 jsr pc,pstr jsr r5,mesg < -- Cannot open file\n\0>; .even mov $12,r0 /set condition code to 12 jmp done callout: sys stat; name; statb bes fserr mov statb+4,r0 bic $!60000,r0 beq 1f cmp r0,$40000 beq expand rts pc 1: mov $dir,r1 clr -(sp) 1: tst (r1) bne 3f tst (sp) bne 2f mov r1,(sp) 2: add $dirsiz,r1 cmp r1,edir blo 1b mov (sp)+,r1 bne 4f jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done 4: jsr r5,verify; 'a rts pc jsr r5,encode; name br 2f 3: jsr r5,decode; name1 mov $name,r2 mov $name1,r3 3: cmpb (r2)+,(r3) bne 2b tstb (r3)+ bne 3b tst (sp)+ tstb flu beq 3f cmp time0(r1),statb+32. blo 3f bhi 1f cmp time1(r1),statb+34. bhis 1f 3: jsr r5,verify; 'r rts pc 2: mov statb+4,mode(r1) bis $100000,mode(r1) movb statb+7,uid(r1) movb statb+8,gid(r1) tstb flf beq 2f clrb statb+9. clr statb+10. 2: movb statb+9.,size0(r1) mov statb+10.,size1(r1) mov statb+32.,time0(r1) mov statb+34.,time1(r1) 1: rts pc 5,encode; name br 2f 3: jsr r5,decode; name1 mov $name,r2 mov $name1,r3 3: cmpb (r2)+,(r3) bne 2b tstb (r3)+ bne 3b tst (sp)+ tstb flu beq 3f cmp time0(r1),statb+32. blo 3f bhi 1f cmp time1(r1),statb+34. bhis 1f 3: jsr r5,verify; 'r rts pc 2: mov statb+4,mode(r1) bis $100000,mode(r1) movb statb+7,uid(r1) movb statb+8,gid(r1) tstb flf beq 2f clrb statb+9. clr statb+10. 2: movb statb+9.,size0(r1) mov statb+10.,size1(r1) mov statb+32.,time0(r1) mov statb+34.,tim/ / / / UNIX SUPPORT GROUP MODIFICATION 2.36 / / tap3 -- dec-tape lod/dmp gettape: mov $dir,r1 clr -(sp) 1: tst (r1) beq 2f jsr r5,decode; name cmp rnarg,$2 ble 4f mov $name,r2 mov *parg,r3 3: tstb (r3) beq 3f cmpb (r2)+,(r3)+ beq 3b br 2f 3: tstb (r2) beq 4f cmpb (r2),$'/ bne 2f 4: mov r1,-(sp) jsr pc,*(r5) mov (sp)+,r1 inc (sp) 2: add $dirsiz,r1 cmp r1,edir blo 1b tst (sp)+ bne 2f cmp rnarg,$2 ble 2f mov *parg,r1 jsr pc,pstr jsr r5,mesg < not found\n\0>; .even 2: dec narg add $2,parg cmp narg,$2 bgt gettape tst (r5)+ rts r5 delete: jsr r5,verify; 'd rts pc jsr pc,clrent rts pc numb: mov r1,-(sp) mov r0,-(sp) clr r0 br 1f numbx: mov r1,-(sp) mov r0,-(sp) movb size0(r1),r0 1: mov $catlb,r2 1: mov $" ,(r2)+ cmp r2,$catlb+12. blo 1b cmp (r5),$2 bne 1f mov $"00,-2(r2) 1: mov (sp)+,r1 jsr pc,numb2 mov (r5)+,r0 sub r0,r2 mov r2,0f mov r0,0f+2 mov $1,r0 sys 0; 9f .data 9: sys write; 0:..; .. .text mov (sp)+,r1 rts r5 numb1: clr r0 numb2: div $10.,r0 mov r1,-(sp) mov r0,r1 beq 1f jsr pc,numb1 1: mov (sp)+,r0 add $'0,r0 movb r0,(r2)+ rts pc update: jsr pc,bitmap mov $dir,r1 1: tst (r1) beq 2f bit $100000,mode(r1) beq 2f tstb size0(r1) bne 9f tst size1(r1) beq 2f 9: mov ndentd8,-(sp) inc (sp) movb size0(r1),r2 mov size1(r1),r3 add $511.,r3 adc r2 ashc $-9,r2 mov r3,size 3: mov (sp),r2 mov size,r3 4: jsr pc,bitcalc inc r2 bitb (sp)+,map(r0) bne 4f sob r3,4b mov (sp)+,tapea(r1) jsr pc,setmap br 2f 4: inc (sp) br 3b 2: add $dirsiz,r1 cmp r1,edir blo 1b jsr pc,wrdir update1: mov $dir,r1 clr -(sp) mov $-1,-(sp) 1: tst (r1) beq 2f bit $100000,mode(r1) beq 2f cmp tapea(r1),(sp) bhis 2f mov tapea(r1),(sp) mov r1,2(sp) 2: add $dirsiz,r1 cmp r1,edir blo 1b tst (sp)+ mov (sp)+,r1 bne 1f rts pc 1: bic $100000,mode(r1) movb size0(r1),mss mov size1(r1),r2 bne 4f tst mss beq update1 4: jsr r5,decode; name mov tapea(r1),r0 jsr pc,wseek clr r3 sys open; name; 0 bes phserr mov r0,r3 3: tst mss bne 4f cmp r2,$512. blo 3f 4: mov r3,r0 sys read; tapeb; 512. bes phserr cmp r0,$512. bne phserr jsr pc,twrite sub $512.,r2 sbc mss br 3b 3: mov r2,0f beq 3f mov r3,r0 sys 0; 9f .data 9: sys read; tapeb; 0:.. .text bes phserr cmp r0,0b bne phserr jsr pc,twrite 3: mov r3,r0 sys read; tapeb; 512. bes phserr tst r0 bne phserr mov r3,r0 sys close 2: jmp update1 phserr: mov r1,-(sp) mov $name,r1 jsr pc,pstr jsr r5,mesg < -- Phase error\n\0>; .even mov (sp)+,r1 clr time0(r1) / time beq 2b sys close br 2b bitmap: mov $map,r0 1: clr (r0)+ cmp r0,$emap blo 1b mov $dir,r1 1: tst (r1) beq 2f bit $100000,mode(r1) bne 2f tst size1(r1) bne 3f tstb size0(r1) beq 2f 3: jsr pc,setmap 2: add $dirsiz,r1 cmp r1,edir blo 1b rts pc setmap: movb size0(r1),r2 mov size1(r1),r3 add $511.,r3 adc r2 ashc $-9.,r2 mov tapea(r1),r2 1: jsr pc,bitcalc bitb (sp),map(r0) bne maperr bisb (sp)+,map(r0) inc r2 sob r3,1b rts pc bitcalc: mov (sp),-(sp) cmp r2,tapsiz  bhis maperr mov r2,r0 bic $!7,r0 mov r0,-(sp) mov $1,r0 als (sp)+,r0 mov r0,2(sp) mov r2,r0 ash $-3,r0 bic $160000,r0 rts pc maperr: jsr r5,mesg ; .even mov $12,r0 /set condition code to 12 jmp done usage: jsr pc,bitmap mov $dir,r2 1: tst (r2) beq 2f inc nentr 2: add $dirsiz,r2 cmp r2,edir blo 1b mov ndentd8,r2 inc r2 mov tapsiz,r3 dec r3 sub ndentd8,r3 1: jsr pc,bitcalc bitb (sp)+,map(r0) beq 2f inc nused mov r2,lused br 3f 2: inc nfree tstb flm bne 1f 3: inc r2 sob r3,1b 1: mov nentr,r0 jsr r5,numb; 4 jsr r5,mesg < entries\n\0>; .even mov nused,r0 jsr r5,numb; 4 jsr r5,mesg < used\n\0>; .even tstb flm bne 1f mov nfree,r0 jsr r5,numb; 4 jsr r5,mesg < free\n\0>; .even 1: mov lused,r0 jsr r5,numb; 4 jsr r5,mesg < last\n\0>; .even rts pc taboc: tstb flv beq 4f mov mode(r1),r0 mov r0,-(sp) ash $-6,r0 bit $40,r0 jsr pc,pmod mov (sp),r0 ash $-3,r0 bit $200,r0 jsr pc,pmod mov (sp)+,r0 bit $1000,r0 jsr pc,pmod clr r0 bisb uid(r1),r0 jsr r5,numb; 4 clr r0 bisb gid(r1),r0 jsr r5,numb; 4 mov tapea(r1),r0 jsr r5,numb; 5 mov size1(r1),r0 jsr r5,numbx; 9. mov r1,-(sp) add $time0,(sp) jsr pc,_localtime mov r0,(sp) mov 10.(r0),r0 jsr r5,numb; 3 mov $'/,r0 jsr pc,putc mov (sp),r0 mov 8.(r0),r0 inc r0 jsr r5,numb; 2 mov $'/,r0 jsr pc,putc mov (sp),r0 mov 6(r0),r0 jsr r5,numb; 2 mov (sp),r0 mov 4(r0),r0 jsr r5,numb; 3 mov $':,r0 jsr pc,putc mov (sp)+,r0 mov 2(r0),r0 jsr r5,numb; 2 mov $' ,r0 jsr pc,putc 4: mov $name,r1 jsr pc,pstr jsr r5,mesg <\n\0> rts pc pmod: beq 1f mov $'s,-(sp) br 2f 1: bit $1,r0 beq 1f mov $'x,-(sp) br 2f 1: mov $'-,-(sp) 2: bit $2,r0 beq 1f mov $'w,-(sp) br 2f 1: mov $'-,-(sp) 2: bit $4,r0 beq 1f mov $'r,r0 br 2f 1: mov $'-,r0 2: jsr pc,putc mov (sp)+,r0 jsr pc,putc mov (sp)+,r0 jsr pc,putc rts pc xtract: movb size0(r1),mss bne 2f tst size1(r1) beq 1f 2: jsr r5,verify; 'x rts pc mov size1(r1),r3 mov tapea(r1),r0 jsr pc,rseek sys unlink; name mov mode(r1),0f sys 0; 9f .data 9: sys creat; name; 0:.. .text bes crterr mov r0,r2 2: tst mss bne 3f cmp r3,$512. blo 2f 3: jsr pc,tread mov r2,r0 sys write; tapeb; 512. bes crterr1 cmp r0,$512. bne crterr1 sub r0,r3 sbc mss br 2b 2: mov r3,0f beq 2f jsr pc,tread mov r2,r0 sys 0; 9f .data 9: sys write; tapeb; 0:.. .text bes crterr1 cmp r0,0b bne crterr1 2: mov r2,r0 sys close movb gid(r1),0f sys 0; 9f .data 9: sys chgrp; name; 0:.. .text movb uid(r1),0f sys 0; 9f .data 9: sys chown; name; 0:.. .text mov time0(r1),r0 mov r1,-(sp) mov time1(r1),r1 / sys 0; 9f .data 9: sys smdate; name .text mov (sp)+,r1 1: rts pc crterr1: clr r0 mov r1,-(sp) clr r1 / sys smdate; name mov (sp)+,r1 mov r2,r0 sys close crterr: mov $name,r1 jsr pc,pstr jsr r5,mesg < -- create error\n\0>; .even rts pc b; 0:.. .text bes crterr1 cmp r0,0b bne crterr1 2: mov r2,r0 sys close movb gid(r1),0f sys 0; 9f .data 9: sys chgrp; name; 0:.. .text movb uid(r1),0f sys 0; / tap4 -- dec-tape lod/dmp .data tc: tcx: mt: mtx: <0\0> tboot: mboot: .even .bss dir: . = .+[mdirent*dirsiz] tapeb: map: .=.+4096. emap: ch: .=.+1 flc: .=.+1 flf: .=.+1 fli: .=.+1 flm: .=.+1 flu: .=.+1 flv: .=.+1 flw: .=.+1 .even command:.=.+2 sum: .=.+2 size: .=.+2 nentr: .=.+2 nused: .=.+2 nfree: .=.+2 lused: .=.+2 catlb: .=.+20. narg: .=.+2 rnarg: .=.+2 parg: .=.+2 fio: .=.+2 mss: .=.+2 ndirent:.=.+2 ndentd8:.=.+2 edir: .=.+2 rseeka: .=.+2 wseeka: .=.+2 tapsiz: .=.+2 name: .=.+32. name1: .=.+32. statb: .=.+40. chgrp = 0. / fake smdate = 30. 0> mboot: .even .bss dir: . = .+[mdirent*dirsiz] tapeb: map: .=.+4096. emap: ch: .=.+1 flc: .=.+1 flf: .=.+1 fli: .=.+1 flm: .=.+1 flu: .=.+1 flv: .=.+1 flw: .=.+1 .even command:.=.+2 sum: .=.+2 size: .=.+2 nentr: .=.+2 nused: .=.+2 nfree: .=.+2 lused: .=.+2 catlb: .=.+20. narg: .=.+2 rnarg: .=.+2 parg: .=.+2 fio: .=.+2 mss: .=.+2 ndirent:.=.+2 ndentd8:.=.+2 edir: .=.+2 rseeka: ./ copy mag tape to disk / entry is made by jsr pc,*$0 / so return can be rts pc / jsr pc,(r5) is putc / jsr pc,2(r5) is getc / jsr pc,4(r5) is mesg 2: jsr pc,4(r5) <'p' for rp03;'f' for rf; 'k' for rk;'4' for rp04\n\0> .even jsr pc,2(r5) cmp r0,$'k bne 3f mov $rkblk,r0 br 1f 3: cmp r0,$'p bne 3f mov $rpblk,r0 br 1f 3: cmp r0,$'f bne 3f mov $rfblk,r0 br 1f 3: cmp r0,$'s bne 3f jsr pc,4(r5) .even br 2b jsr pc,hsinit mov $hsblk,r0 br 1f 3: cmp r0,$'4 bne 2b hpcs1 = 176700 hpcs2 = 176710 hpof = 176732 fmt22 = 010000 preset = 021 clear = 040 hpinit: mov $hpcs1,r3 mov $clear,8.(r3) mov $preset,(r3) mov $fmt22,26.(r3) mov $hpblk,r0 1: mov r0,wxblk mov $'\n,r0 jsr pc,(r5) 2: jsr pc,4(r5) <'m' for tm11; 'u' for tu16;'c' for tc11\n\0> .even jsr pc,2(r5) cmp r0,$'m bne 3f mov $tmblk,rblk mov $tmrew,rew br 1f 3: cmp r0,$'u bne 3f mov $tublk,rblk mov $turew,rew br 1f 3: cmp r0,$'c bne 2b mov $tcblk,rblk mov $tcrew,rew 1: mov $'\n,r0 jsr pc,(r5) jsr pc,4(r5) .even jsr pc,numb mov r0,bno jsr pc,4(r5) .even jsr pc,*rew jsr pc,numb mov r0,r1 beq 2f mov r0,tapa cmp rblk,$tcblk beq 2f 1: jsr pc,*rblk dec r1 bne 1b 2: jsr pc,4(r5) .even jsr pc,numb mov r0,r1 1: jsr pc,*rblk jsr pc,wblk inc tapa dec r1 bne 1b jsr pc,*rew rts pc numb: clr r1 1: jsr pc,2(r5) cmp r0,$'\n beq 1f sub $'0,r0 cmp r0,$9 bhi 2f mul $10.,r1 add r0,r1 br 1b 1: mov r1,r0 rts pc 2: jsr pc,4(r5) .even tst (sp)+ rts pc mts = 172520 mtc = 172522 mtbrc = 172524 mtcma = 172526 tmblk: bit $2,*$mts bne tmblk tstb *$mtc bge tmblk mov $-512.,*$mtbrc mov $buf,*$mtcma mov $60003,*$mtc 1: tstb *$mtc bge 1b tst *$mtc bge 1f jsr pc,4(r5) .even mov $-1,*$mtbrc mov $60013,*$mtc br tmblk 1: rts pc tmrew: mov $60017,*$mtc rts pc tucs1 = 172440 tuwc = 172442 tuba = 172444 tufc = 172446 tucs2 = 172450 tuds = 172452 tutc = 172472 tublk: bit $020000,*$tuds bne tublk tstb *$tucs1 bge tublk mov $-256.,*$tuwc mov $buf,*$tuba mov $071,*$tucs1 1: tstb *$tucs1 bge 1b bit $040000,*$tucs1 beq 1f jsr pc,4(r5) .even mov $040,*$tucs2 mov $-1,*$tufc mov $033,*$tucs1 br tublk 1: rts pc turew: mov $040,*$tucs2 mov $07,*$tucs1 rts pc tcdt = 177350 tccm = 177342 tcblk: mov r1,sav mov $tcdt,r0 mov $tccm,r1 for: mov $3,(r1) / rbn for 1: tstb (r1) bge 1b tst (r1) blt rev cmp tapa,(r0) beq rd bgt for rev: mov $4003,(r1) / rbn bac 1: tstb (r1) bge 1b tst (r1) blt for mov (r0),r2 add $5,r2 cmp tapa,r2 blt rev br for rd: mov $buf,-(r0) / bus addr mov $-256.,-(r0) / wc mov $5,-(r0) / read 1: tstb (r1) bge 1b tst (r1) blt tcblk mov sav,r1 rts pc tcrew: mov $4003,tccm rts pc wblk: mov bno,r0 inc bno mov r1,-(sp) mov r0,r1 clr r0 jmp *wxblk rpda = 176724 rpblk: div $10.,r0 mov r1,-(sp) mov r0,r1 clr r0 div $20.,r0 bisb r1,1(sp) mov $rpda,r1 mov (sp)+,(r1) mov r0,-(r1) br 1f rfda = 177466 rfblk: div $8.,r0 mov r0,sav ash $-5.,r0 mov r0,*$rfda+2 mov sav,r0 ash $11.,r0 mov r0,-(sp) mul $256.,r1 bis r1,(sp) mov $rfda,r1 mov (sp)+,(r1) br 1f rkda = 177412 rwrite = 03 rkblk: div $12.,r0 ash $4.,r0 bis r1,r0 mov $rkda,r1 mov r0,(r1) 1: mov $buf,-(r1) mov $-256.,-(r1) mov $3,-(r1) br intr hpda = 176724 hpdc = 176734 hpblk: div $22.,r0 mov r1,-(sp) mov r0,r1 clr r0 div $19.,r0 bisb r1,1(sp) mov $hpcs1+8.,r1 mov r0,20.(r1) mov (sp)+,r0 br 1f hscs1 = 172040 hsdt = 172066 clear = 040 hsinit: mov $clear,$hscs1 mov $4.,sav tst $hsdt bne 2f mov $8.,sav 2: rts pc hsda = 172046 hwrite = 061 hsblk: div $sav,r0 ash $6.,r0 bis r1,r0 mov $hsda+2,r1 1: mov r0,-(r1) mov $buf,-(r1) mov $-256.,-(r1) mov $hwrite,-(r1) 1: intr: tstb (r1) bge 1b tst (r1) blt 1f mov (sp)+,r1 rts pc 1: jsr pc,4(r5) .even mov (sp)+,r1 dec bno br wblk .bss buf: .=.+512. rblk: .=.+2 wxblk: .=.+2 rew: .=.+2 tapa: .=.+2 bno: .=.+2 sav: .=.+2 s1 = 172040 hsdt = 172066 clear = 040 hsinit: mov $clear,$hscs1 mov $4.,sav tst $hsdt bne 2f mov $8.,sav 2: rts pc hsda = 172046 hwrite = 061 hsblk: div $sav,r0 ash $6.,r0 bis r1,r0 mov $hsda+2,r1 1: mov r0,-(r1) mov $buf,-(r1) mov $-256.,-(r1) mov $hwrite,-(r1) 1: intr: tstb (r1) bge 1b tst (r1) blt 1f mov (sp)+,r1 rts pc 1: jsr pc,4(r5) .even mov (sp)+,r1 dec bno br wblk .bss buf: .=.+512. rblk: .=.+2 wxblk: .=.+2 rew: .=.+2 tapa: .=.+2 bno: .=.+2/ copy and execute DEC loaders core = 24. prs = 177550 mov $dldr,r0 mov $[core*2048.]-300,r1 mov r1,r2 1: mov (r0)+,(r1)+ cmp r0,$end blo 1b jmp (r2) dldr: 10706 24646 10705 62705 114 5001 13716 177570 6016 103402 5016 404 241 6116 1001 10116 5000 4715 105303 1374 4715 4767 74 10402 162702 4 22702 2 1441 4767 54 61604 10401 4715 2004 105700 1753 0 751 110321 770 16703 150 105213 105713 100376 116303 2 60300 42703 177400 5302 207 12667 44 4715 10304 4715 303 50304 16707 26 4767 177752 4715 105700 1342 6204 103002 0 677 6304 114 0 . = dldr-500+744 16701 26 12702 352 5211 105711 100376 116162 2 [core*2048.]-400 5267 177756 765 prs end: 03402 5016 404 241 6116 1001 10116 5000 4715 105303 1374 4715 4767 74 10402 162702 4 22702 2 1441 4767 54 61604 10401 4715 2004 105700 1753 0 751 110321 770 16703 150 105213 105713 100376 116303 2 60300 42703 177400 5302 207 12667 44 4715/ dli -- DEC format tape interpreter .globl fopen, fcreat, getc, putc, flush, mesg mov (sp)+,r5 cmp r5,$1 bne 1f jsr r5,mesg; ; .even sys exit 1: tst (sp)+ mov (sp)+,r0 jsr r5,fcreat; obuf bec 1f jsr r5,mesg; ; .even 1: mov $ppt,r0 cmp r5,$3 blt 1f mov (sp)+,r0 1: jsr r5,fopen; ibuf bec 1f jsr r5,mesg; ; .even sys exit 1: jsr pc,get tst r0 beq 1b cmp r0,$1 bne err jsr pc,get jsr pc,get mov r0,-(sp) jsr pc,get swab r0 bis r0,(sp) jsr pc,get mov r0,r1 jsr pc,get swab r0 bis r0,r1 sub $6,(sp) ble 2f cmp r1,origin beq 3f mov r1,origin jsr r5,flush; obuf mov obuf,r0 sys seek; origin: 0; 0 3: jsr pc,get jsr pc,put dec (sp) bgt 3b tst (sp)+ jsr pc,get br 1b 2: jsr r5,flush; obuf sys exit put: jsr r5,putc; obuf inc origin rts pc get: jsr r5,getc; ibuf bec 1f err: jsr r5,flush; obuf jsr r5,mesg; ; .even sys exit 1: rts pc ppt: .even .bss count: .=.+2 ch: .=.+2 ibuf: .=.+520. obuf: .=.+520. ,r1 jsr pc,get swab r0 bis r0,r1 sub $6,(sp) ble 2f cmp r1,origin beq 3f mov r1,origin jsr r5,flush; obuf mov obuf,r0 sys seek; origin: 0; 0 3: jsr pc,get jsr pc,put dec (sp) bgt 3b tst (sp)+ jsr pc,get br 1b 2: jsr r5,flush; obuf sys exit put: jsr r5,putc; obuf inc origin rts pc get: jsr r5,getc; ibuf bec 1f err: jsr r5,flush; obuf jsr r5,mesg; ; .even sys exit 1: rts pc ppt: .even .bss count: .=.+2 ch: .=.+2 ibuf: .=/ unix DEC-tape time/mtrack track formatter nword = 256. nblock = 578. endz = 7200. ps = 177776 tcst = 177340 tccm = 177342 tcwc = 177344 tcba = 177346 tcdt = 177350 mov r5,savr5 mov sp,savsp start: mov savr5,r5 mov savsp,sp jsr pc,4(r5) .even clr r0 mov $cobtab,r1 1: jsr pc,bcomobv mov r2,(r1)+ inc r0 cmp r0,$512. bne 1b mov $buffer,r0 1: mov $-1,(r0)+ cmp r0,$buffer+nword+nword blo 1b mov savr5,r5 jsr pc,2(r5) mov $340,ps mov $tcdt,r5 mov $13,tccm jsr pc,flag / 8Kch for end zone mov $endz,r4 1: jsr r0,mtrack; 101101 dec r4 bne 1b / foreward guard mov $199.,r4 1: jsr r0,mtrack; 10101 dec r4 bne 1b / blocks mov $nblock,r3 1: jsr r0,mtrack; 10101 jsr r0,mtrack; 10110 jsr r0,mtrack; 11010 jsr r0,mtrack; 01000 jsr r0,mtrack; 01000 jsr r0,mtrack; 01000 jsr r0,mtrack; 01000 mov $nword-4,r4 2: jsr r0,mtrack; 111000 dec r4 bne 2b jsr r0,mtrack; 111011 jsr r0,mtrack; 111011 jsr r0,mtrack; 111011 jsr r0,mtrack; 111011 jsr r0,mtrack; 101001 jsr r0,mtrack; 100101 jsr r0,mtrack; 10101 dec r3 bne 1b / rear guard mov $199.,r4 1: jsr r0,mtrack; 10101 dec r4 bne 1b / rear end zone mov $endz,r4 1: jsr r0,mtrack; 10010 dec r4 bne 1b clr tccm / end of mtrack pass / go back 12 blocks mov $12.,r0 mov $4002,tccm 1: incb tccm jsr pc,flag dec r0 bne 1b / put comobv(nblock-1) in everything / up to end zone mov $nblock-1,r0 mov r0,bn jsr pc,comobv mov $17,tccm jsr pc,flag 1: movb r1,tcst mov r0,(r5) jsr pc,flag1 br 1b / reverse pass put in / foreward and reverse / block numbers mov $4017,tccm jsr pc,flag 1: mov $nword+3.,r4 2: clrb tcst clr (r5) jsr pc,flag dec r4 bne 2b clrb tcst clr (r5) mov bn,r0 jsr pc,comobv jsr pc,flag movb r1,tcst mov r0,(r5) jsr pc,flag dec bn blt check clrb tcst clr (r5) jsr pc,flag clrb tcst clr (r5) jsr pc,flag clrb tcst mov bn,(r5) jsr pc,flag clrb tcst clr (r5) jsr pc,flag clrb tcst clr (r5) jsr pc,flag br 1b / foreward pass / confirm block numbers / write all 1's in data check: clrb tcst clr (r5) jsr pc,flag1 br check clr r4 1: mov $3,tccm jsr pc,flag cmp (r5),r4 bne error1 mov $-nword,tcwc mov $buffer,tcba mov $15,tccm jsr pc,flag inc r4 cmp r4,$nblock bne 1b mov $3,tccm jsr pc,flag1 br error2 / reverse pass / confirm block numbers / read data and compare / to all 1's 1: mov $4003,tccm jsr pc,flag dec r4 cmp r4,(r5) bne error3 mov $-nword,tcwc mov $buffer,tcba mov $4005,tccm jsr pc,compare jsr pc,flag tst r4 bne 1b mov $4003,tccm jsr pc,flag1 br error4 jsr pc,compare jmp start error1: mov $1,r0 br 1f error2: mov $1,r0 br 1f error3: mov $3,r0 br 1f error4: mov $4,r0 br 1f error5: mov $5,r0 br 1f error6: mov $6,r0 br 1f error7: mov $7,r0 1: add $'0,r0 movb r0,0f mov tcst,-(sp) mov tccm,-(sp) mov $1,tccm mov savr5,r5 jsr pc,4(r5) 0: .even mov (sp)+,r1 mov (sp)+,r0 0 rts pc compare: mov r0,-(sp) mov $buffer,r0 1: cmp (r0)+,$-1 bne error5 cmp r0,$buffer+nword+nword blo 1b mov (sp)+,r0 rts pc mtrack: mov (r0)+,(r5) jsr pc,flag rts r0 flag: bit $100200,tccm beq flag blt error6 rts pc flag1: bit $100200,tccm beq flag1 bge 1f tst tcst bge error7 add $2,(sp) 1: rts pc comobv: mov r0,r4 bic $!777,r0 asl r0 mov cobtab(r0),r0 swab r0 clr r1 ror r0 rol r1 asl r0 asl r0 rol r1 swab r4 bic $177401,r4 bis cobtab(r4),r0 rts pc bcomobv: mov r0,r2 bic $!70,r2 mov r0,r3 mov $6.,r4 1: asr r3 dec r4 bne 1b bic $!7,r3 bis r3,r2 mov r0,r3 mov $6.,r4 1: asl r3 dec r4 bne 1b bic $!700,r3 bis r3,r2 com r2 bic $!777,r2 rts pc bn: .=.+2 savr5: .=.+2 savsp: .=.+2 cobtab: .=.+1024. buffer: .=.+nword+nword 1f tst tcst bge error7 add $2,(sp) 1: rts pc comobv: mov r0,r4 bic $!777,r0 asl r0 mov cobtab(r0),r0 swab r0 clr r1 ror r0 rol r1 asl r0 asl r0 rol r1 swab r4 bic $177401,r4 bis cobtab(r4),r0 rts pc bcomobv: mov r0,r2 bic $!70,r2 mov r0,r3 mov $6.,r4 1: asr r3 dec r4 bne 1/ to a unix entry / entry is made by jsr pc,*$0 / so return can be rts pc .hp = 0 .hs = 0 .rf = 0 .rk = 0 .rp = 1 offset = 0. core = 24. .. = [core*2048.]-512. start: mov $..,sp mov sp,r1 cmp pc,r1 bhis 2f reset clr r0 cmp (r0),$407 bne 1f mov $20,r0 1: mov (r0)+,(r1)+ cmp r1,$end blo 1b jmp (sp) 2: mov $inod,r0 1: clr (r0)+ cmp r0,sp blo 1b jsr pc,getc .if .rk cmp r0,$'k bne 2b mov $rkblk,r0 .endif .if .rp cmp r0,$'p bne 2b mov $rpblk,r0 .endif .if .rf 3: cmp r0,$'f bne 2b mov $rfblk,r0 .endif .if .hs 3: cmp r0,$'s bne 2b hscs1 = 172040 hsdt = 172066 clear = 040 hsinit: mov $hscs1,r3 mov $clear,(r3) mov $4.,sav tst $hsdt bne 2f mov $8.,sav 2: mov $hsblk,r0 .endif .if .hp 3: cmp r0,$'4 bne 2b hpcs1 = 176700 hpcs2 = 176710 hpof = 176732 fmt22 = 010000 preset = 021 clear = 040 hpinit: mov $hpcs1,r3 mov $clear,8.(r3) mov $preset,(r3) mov $fmt22,26.(r3) mov $hpblk,r0 .endif 1: mov r0,rxblk mov $'\n,r0 jsr pc,putc mov $names,r1 1: mov r1,r2 2: jsr pc,getc cmp r0,$'\n beq 1f cmp r0,$'/ beq 3f movb r0,(r2)+ br 2b 3: cmp r1,r2 beq 2b add $14.,r1 br 1b 1: mov $names,r1 mov $1,r0 1: clr bno jsr pc,iget tst (r1) beq 1f 2: jsr pc,rmblk br start mov $buf,r2 3: mov r1,r3 mov r2,r4 add $16.,r2 tst (r4)+ beq 5f 4: cmpb (r3)+,(r4)+ bne 5f cmp r4,r2 blo 4b mov -16.(r2),r0 add $14.,r1 br 1b 5: cmp r2,$buf+512. blo 3b br 2b 1: clr r1 1: jsr pc,rmblk br 1f mov $buf,r2 2: mov (r2)+,(r1)+ cmp r2,$buf+512. blo 2b br 1b 1: clr r0 cmp (r0),$407 bne 2f 1: mov 20(r0),(r0)+ cmp r0,sp blo 1b 2: jsr pc,*$0 br start iget: add $31.,r0 mov r0,r5 ash $-4.,r0 jsr pc,rblk bic $!17,r5 ash $5.,r5 add $buf,r5 mov $inod,r4 1: mov (r5)+,(r4)+ cmp r4,$addr+16. blo 1b rts pc rmblk: add $2,(sp) mov bno,r0 inc bno bit $LRG,mode bne 1f asl r0 mov addr(r0),r0 bne rblk 2: sub $2,(sp) rts pc 1: clr -(sp) movb r0,(sp) clrb r0 swab r0 asl r0 mov addr(r0),r0 beq 2b jsr pc,rblk mov (sp)+,r0 asl r0 mov buf(r0),r0 beq 2b rblk: mov r1,-(sp) mov r0,r1 clr r0 jmp *rxblk .if .rk rkda = 177412 rkblk: div $12.,r0 ash $4.,r0 bis r1,r0 mov $rkda+2,r1 .endif .if .rp rpda = 176724 rpblk: div $10.,r0 mov r1,-(sp) mov r0,r1 clr r0 div $20.,r0 add $offset,r0 bisb r1,1(sp) mov $rpda,r1 mov (sp)+,(r1) .endif .if .rf rfda = 177466 rfblk: div $8.,r0 mov r0,sav ash $-5.,r0 mov r0,*$rfda+2 mov sav,r0 ash $11.,r0 mov r0,-(sp) mul $256.,r1 bis r1,(sp) mov $rfda+2,r1 mov (sp)+,r0 br 1f .endif .if .hp hpda = 176706 hpdc = 176734 hpblk: div $22.,r0 mov r1,-(sp) mov r0,r1 clr r0 div $19.,r0 bisb r1,1(sp) mov $hpcs1+8.,r1 add $offset,r0 mov r0,20.(r1) mov (sp)+,r0 .endif .if .hs hsda = 172046 hsblk: div $sav,r0 ash $6.,r0 bis r1,r0 mov $hsda+2,r1 .endif hread = 071 rread = 05 1: mov r0,-(r1) mov $buf,-(r1) mov $-256.,-(r1) .if .hp mov $hread,-(r1) .endif .if .hs mov $hread,-(r1) .endif .if .rf mov $rread,-(r1) .endif .if .rk mov $rread,-(r1) .endif .if .rp mov $rread,-(r1) .endif 1: tstb (r1) bge 1b mov (sp)+,r1 rts pc tks = 177560 tkb = 177562 getc: mov $tks,r0 inc (r0) 1: tstb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1f cmp r0,$'Z bhi 1f add $40,r0 1: cmp r0,$'\r bne putc mov $'\n,r0 tps = 177564 tpb = 177566 putc: tstb tps bge putc cmp r0,$'\n bne 1f mov $'\r,r0 jsr pc,putc mov $'\n+200,r0 jsr pc,putc clr r0 jsr pc,putc mov $'\n,r0 rts pc 1: mov r0,tpb rts pc end: inod = ..-1024. mode = inod addr = inod+8. buf = inod+32. bno = buf+514. rxblk = bno+2 sav = rxblk+2 names = sav+2 LRG = 10000 reset = 5 / disk boot program to load and transfer tb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1f cmp r0,$'Z bhi 1f add $40,r0 1: cmp r0,$'\r bne putc mov $'\n,r0 tps = 177564 tpb = 177566 putc: tstb tps bge putc cmp r0,$'\n bne 1f mov $'\r,r0 jsr pc,putc mov $'\n+200,r0 jsr pc,putc clr r0 jsr pc,putc mov $'\n,r0 rts pc 1: mov r0,tpb rts pc end: inod = ..-1024. mode = inod addr = inod+8. buf = inod+32. bno = buf+514. rxblk = bno+/ tape boot program to load and transfer / to a 'tp' entry / entry is made by jsr pc,*$0 / so return can be rts pc / jsr pc,(r5) is putc / jsr pc,2(r5) is getc / jsr pc,4(r5) is mesg tmsize = 62. tcsize = 24. start: 2: jsr pc,4(r5) <'m' for tm11; 'c' for tc11 ; 'u' for tu16\n\0> .even jsr pc,2(r5) mov $tmsize,tpsize cmp r0,$'m bne 3f mov $tmblk,rblk mov $tmrew,rew br 1f 3: cmp r0,$'c bne 3f mov $tcblk,rblk mov $tcrew,rew mov $tcsize,tpsize br 1f 3: cmp r0,$'u bne 2b mov $tublk,rblk mov $turew,rew 1: jsr pc,*rew jsr pc,4(r5) <\nTape entries\n\0> .even jsr pc,*rblk clr tapa tread: inc tapa cmp tapa,tpsize bhi 4f jsr pc,*rblk mov $buf,r1 1: mov r1,r2 tstb (r1) beq 2f jsr pc,string 2: cmp r2,r1 beq 2f 3: mov r1,-(sp) clr r0 mov 38.(r2),r1 div $512.,r0 tst r1 beq 3f inc r0 3: add r0,wc mov (sp)+,r1 2: mov r2,r1 add $64.,r1 cmp r1,$buf+512. blo 1b br tread 4: jsr pc,psize rts pc psize: jsr pc,*rew jsr pc,4(r5) <\nTape size = \0> .even mov $bsize,r2  mov wc,r1 add tpsize,r1 add $1,r1 2: clr r0 div $10.,r0 add $'0,r1 movb r1,(r2)+ mov r0,r1 tst r0 bne 2b 2: mov $size,r0 3: movb -(r2),(r0)+ cmp $bsize,r2 blo 3b movb $'\n,(r0)+ clrb (r0) mov $size,r1 jsr pc,string jsr pc,4(r5) <(decimal)\n\0> .even rts pc mts = 172520 mtc = 172522 mtbrc = 172524 mtcma = 172526 tmblk: bit $2,*$mts bne tmblk tstb *$mtc bge tmblk mov $-512.,*$mtbrc mov $buf,*$mtcma mov $60003,*$mtc 1: tstb *$mtc bge 1b tst *$mtc bge 1f jsr pc,4(r5) .even mov $-1,*$mtbrc mov $60013,*$mtc br tmblk 1: rts pc tmrew: mov $60017,*$mtc rts pc tucs1 = 172440 tuwc = 172442 tuba = 172444 tufc = 172446 tucs2 = 172450 tuds = 172452 tutc = 172472 tublk: bit $020000,*$tuds bne tublk tstb *$tucs1 bge tublk mov $-256.,*$tuwc mov $buf,*$tuba mov $071,*$tucs1 1: tstb *$tucs1 bge 1b bit $040000,*$tucs1 beq 1f jsr pc,4(r5) .even mov $040,*$tucs2 mov $-1,*$tufc mov $033,*$tucs1 br tublk 1: rts pc turew: mov $040,*$tucs2 mov $07,*$tucs1 rts pc tcdt = 177350 tccm = 177342 tcblk: mov $tcdt,r0 mov $tccm,r1 for: mov $3,(r1) / rbn for 1: tstb (r1) bge 1b tst (r1) blt rev cmp tapa,(r0) beq rd bgt for rev: mov $4003,(r1) / rbn bac 1: tstb (r1) bge 1b tst (r1) blt for mov (r0),r2 add $5,r2 cmp tapa,r2 blt rev br for rd: mov $buf,-(r0) / bus addr mov $-256.,-(r0) / wc mov $5,-(r0) / read 1: tstb (r1) bge 1b tst (r1) blt tcblk rts pc tcrew: mov $4003,tccm rts pc tks = 177560 tkb = 177562 getc: mov $tks,r0 inc (r0) 1: tstb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1f cmp r0,$'Z bhi 1f add $40,r0 1: cmp r0,$'\r bne putc mov $'\n,r0 tps = 177564 tpb = 177566 putc: tstb tps bge putc cmp r0,$'\n bne 1f mov $'\r,r0 jsr pc,(r5) mov $'\n+200,r0 jsr pc,(r5) clr r0 jsr pc,(r5) mov $'\n,r0 rts pc 1: mov r0,tpb rts pc mesg: movb *(sp),r0 beq 1f jsr pc,(r5) inc (sp) br mesg 1: add $2,(sp) bic $1,(sp) rts pc string: clr r4 2: tstb (r1) beq 2f cmpb (r1),$'! blo 3f cmpb (r1),$0176 bhi 3f movb (r1)+,r0 jsr pc,(r5) inc r4 cmp $32.,r4 bhi 2b 2: mov $'\n,r0 jsr pc,(r5) 3: rts pc .bss buf: .=.+512. tapa: .=.+2 rblk: .=.+2 rew: .=.+2 tpsize: .=.+2 wc: .=.+2 bsize: .=.+32. size: .=.+32. mov $'\r,r0 jsr pc,(r5) mov $'\n+200,r0 jsr pc,(r5) clr r0 jsr pc,(r5) mov $'\n,r0 rts pc 1: mov r0,tpb rts pc mesg: movb *(sp),r0 beq 1f jsr pc,(r5) inc (sp) br mesg 1: add $2,(sp) bic $1,(sp) rts pc string: clr r4 2: tstb (r1) beq 2f/bin/if $1x != x /bin/goto $1 : 45 : 70 /bin/echo 11/$1 /bin/ld -x -r -d low.o mch.o conf.o lib1 lib2 sysfix a.out gorp /bin/mv gorp a.out /bin/exit : 40 /bin/echo 11/40 /bin/ld -x low.o mch.o conf.o lib40 lib1 lib2 /bin/exit e: .=.+32. size: .=.+32. mov $'\r,r0 jsr pc,(r5) mov $'\n+200,r0 jsr pc,(r5) clr r0 jsr pc,(r5) mov $'\n,r0 rts pc 1: mov r0,tpb rts pc mesg: movb *(sp),r0 beq 1f jsr pc,(r5) inc (sp) br mesg 1: add $2,(sp) bic $1,(sp) rts pc string: clr r4 2: tstb (r1) beq 2f# #include "mkconf.h" # /* * UNIX SUPPORT GROUP MODIFICATION ?.?? */ /* * Revised Jan 1977 by TMR */ #define EOT 0 #define CONTINUE 1 #define MAXLOW 01000 #define LOW 0400 #define EGOOD 0 #define EBAD 1 char *z; struct tab *vect[118]; int flagf, flagb, flagm, flags; int nkl; int lastc 0; int lowend LOW; /* End of low core */ char *dev; int log; main(argc,argv) int argc; char **argv; { register struct tab *p; register struct ord *q; int *y; int i, n, ev,*s; char *ap; struct tab *search(); extern fout; argv++; argc--; flagf = flagb = flags = 1; if(argc&&(argv[0][0] == '-')){ ap = argv[0]; while(*++ap){ switch(*ap){ default: printf("%c: Not an option\n",*ap); exit(); case 'a': if(digit(argv[1][0])){ lowend = atoi(argv[1],8); if((lowend < 0)||(lowend > 01000)){ printf("low core ends at 0777!\n"); exit(1); } printf("End of low core - %o\n",lowend); }else{ printf("%s: not an address!\n",argv[1]); exit(1); } continue;  case 'n': flags = 0; continue; case 't': flags = 2; continue; } } } dev = "console"; set(p = lookup("console")); install(p,060,p->size); dev = "clock"; set(p = lookup("clock")); install(p,0100,p->size); install(p,0104,p->size); dev = "mem"; set(p = lookup("mem")); for(s= &vect[30];s<&vect[33];s++) *s = RESERVED; while(input()); /* * pass1 -- create interrupt vectors */ nkl = 0; flush(); if((fout = creat("l.s", 0666)) <0){ fout = 0; printf("Can't create l.s\n"); flush(); exit(1); } flush(); if(memflg == -1) puke(stra40); else puke(stra); low(); if(flagb) puke(strb); puke(strd); for(p=table; p->name; p++){ if(p->count != 0 && p->key & INTR){ printf("\n%s%s", p->codeb, p->codec); } } flush(); if(flags == 1) printf("\n.globl\t_stray\nstray:\tjsr\tr0,call; _stray\n"); printf("\n"); flush(); close(fout); /* * pass 2 -- create configuration table */ init(); z = search(&std); if((fout = creat("c.c", 0666))<0){ fout = 0; printf("Can't create c.c\n"); flush(); exit(1); } puke(stre); i = 0; for(q= &border[0] ; q->name ; q++){ printf("/*%2.2d*/",i++); if(q->flag) printf("%s\n", q->addr->coded); else printf("%s\n",z->coded); } puke(strf); i = 0; for(q = &corder[0] ; q->name ; q++){ printf("/*%2.2d*/",i++); if(q->flag) printf("%s\n", q->addr->codee); else printf("%s\n",z->codee); } puke(strg); i = 0; for(q = &dorder[0] ; q->name ; q++){ printf("/*%2.2d*/",i++); if(q->flag) printf("%s\n", q->addr->codef); else printf("%s\n",z->codef); } puke(strh); printf("\nint\trootdev\t{(%d<<8)|%d};\n",rootdev.hibyte&0377, rootdev.lobyte&0377); printf("int\tswapdev\t{(%d<<8)|%d};\n",swapdev.hibyte&0377, swapdev.lobyte&0377); printf("int\tswplo\t%d;\n",swplo); printf("int\tnswap\t%d;\n",nswap); printf("\n\n"); puke(stri); if(log){ printf("int\t*errtabs[]{\n"); for(q= &border[0];q->name;q++){ if(q->flag) printf("\t%s\n",q->addr->codeg); } printf("\t0};\n"); } flush(); close(fout); fout = 0; if(lowend != LOW){ printf("End of low core %o\n",lowend); } flush(); exit(EGOOD); } /* * Print string */ puke(s) char **s; { char *c; while(c = *s++) printf("%s\n", c); } char *lp; char line[100]; char *arg[4]; /* * Read input and build vector array */ input() { int ind,ix; register char *p; char *sp; register struct tab *q; register char c; int n; struct ord *o; char *s,*t; int i,count, addr,v,f; /* * force initial typing of 40, 45, or 70 */ ix = 0; for(i=0;i<4;i++){ arg[i] = 0; } p = line; arg[0] = line; ind = 0; lastc = ' '; while((c=get()) != '\n') { if(c == '\0') return(EOT); if((c == ' ')||(c == '\t')){ continue; } sp = p; if(alpha(c)){ do { *p++ = c; c = get(); }while(alpha(c)||digit(c)); *p++ = '\0'; lastc = c; goto sarg; } if(digit(c)){ do { *p++ = c; c = get(); }while(digit(c)); *p++ = '\0'; lastc = c; goto sarg; } goto skip; sarg: arg[ind++] = sp; skip: ; } if(p == line) return(CONTINUE); *p++ = '\0'; for(;memflg == -2;){ if(equal("45",arg[0])){ memflg = 1; return(CONTINUE); }else if(equal("70",arg[0])){ memflg = 1; vect[9] = lookup("parity"); return(CONTINUE); }else if(equal("34",arg[0])||equal("40",arg[0])){ memflg = -1; return(CONTINUE); }else{ printf("Which processor? 40? 34? 45? 70?\n"); return(CONTINUE); } return(0); } if(equal("root",arg[0])){ if((ind == 3)||(ind == 2)){ ; }else{ printf("root: Arg count!\n"); return(CONTINUE); } if(lookup(arg[1]) == FALSE){ printf("root: %s Unknown device?\n",arg[1]); return(CONTINUE); } n = 0; if(ind == 3) n = atoi(arg[2],10); if((n < 0)||(n >=256)){ printf("root: %s Minor device number out of range\n",arg[2]); return(CONTINUE); } rootdev.lobyte = n; i = 0; f = 0; for(o = &border[0];o->name;o++){ if(equal(o->name,arg[1])){ if((o->flag&BLOCK) == 0){ printf("root: %s Not in Block Device Table\n", arg[1]);  swapdev = SWAPDEV; rootdev = ROOTDEV; return(CONTINUE); } f++; break; } i++; } if(f == 0){ printf("root: %s Device not in Configuration Table!\n", arg[1]); return(CONTINUE); } rootdev.hibyte = i; return(CONTINUE); }else if(equal("swap",arg[0])){ if((ind == 3)||(ind == 2)){ ; }else{ printf("swap: Arg count!\n"); return(CONTINUE); } if(lookup(arg[1]) == FALSE){ printf("swap: %s Unknown device?\n",arg[1]); return(CONTINUE); } n = 0; if(ind == 3) n = atoi(arg[2],10); if((n < 0)||(n >= 256)){ printf("swap: %s Minor device number out of range\n", arg[2]); return(CONTINUE); } swapdev.lobyte = n; i = 0; f = 0; for(o = &border[0];o->name;o++){ if(equal(o->name,arg[1])){ if((o->flag&BLOCK) == 0){ printf("swap: %s not in Block Device Table\n", arg[1]); return(CONTINUE); } f++; break; } i++; } if(f == 0){ printf("swap: %s Device not in Configuration Table!\n", arg[1]); return(CONTINUE); } swapdev.hibyte = i; return(CONTINUE); }else if(equal("swplo",arg[0])){ if(ind != 2){ printf("swplo: Arg count\n"); return(CONTINUE); } if(digit(arg[1][0]) == FALSE){ printf("swplo: %s swap offset?\n",arg[1]); return(CONTINUE); } i = 0; if((i = atoi(arg[1],10)) == 0){ printf("Swap offset cannot be zero!\n"); return(CONTINUE); } swplo = i; return(CONTINUE); }else if(equal("nswap",arg[0])){ if(ind != 2){ printf("nswap: Arg count\n"); return(CONTINUE); } if(digit(arg[1][0]) == FALSE){ printf("nswap: %s number of swap blocks?\n",arg[1]); return(CONTINUE); } nswap = atoi(arg[1],10); return(CONTINUE); }else if(equal("list",arg[0])){ list(); return(CONTINUE); }else if(equal("location",arg[0])){ location(); return(CONTINUE); }else if(equal("errorlog",arg[0])){ log++; return(CONTINUE); }else if(equal("q",arg[0])||equal("quit",arg[0])){ exit(1); } n = 0; ix = 0; dev = arg[0]; if(digit(arg[0][0])){ dev = arg[1]; n = atoi(arg[0],10); ix++; } if(n == 0) n = 1; f = 0; for(q=table;q->name;q++){ if(equal(q->name,dev)){ f++; break; } } if(f == 0){ printf("%s: Unknown device!\n",dev); return(CONTINUE); } s = arg[ix]; if(alpha(*s)){ ix++; } v = 0; t = arg[ix]; if(digit(*t)){ v = atoi(arg[ix],8); if(v&03){ printf("Vectors at double word boundary only!\n"); return(CONTINUE); } } /* * Install device */ if(q->count < 0) { printf("%s: no more, no less\n", dev); return(CONTINUE); } if((q->address < 0300) && (n + q->count > 1)) { q->count = 1; printf("%s: only one\n", dev); return(CONTINUE); } count = q->count; if(q->count < 0) count = 0; for(i=0;iaddress + (i+count) * q->size; else addr = v + i * q->size; if(q->key&EVEN){ if((addr&07) != 0){ printf("Even address required for %s!\n",dev); printf("Specify %o instead\n", (addr+7)&0177770); return(CONTINUE); } } if(install(q,addr,q->size) == FALSE){ return(CONTINUE); } } q->count =+ n; set(q); return(CONTINUE); } /* * Compare two strings */ equal(p, q) char *p, *q; { register char *a, *b; a = p; b = q; while(*a++ == *b) if(*b++ == '\0') return(TRUE); return(FALSE); } /* * Initialize arrays */ init() { register struct ord *p,*q; for(p = &border[0] ; p->name ; p++) p->addr = search(p); for(p = &corder[0] ; p->name ; p++) p->addr = search(p); for(p = &dorder[0] ; p->name ; p++) p->addr = search(p); } /* * Search a config table for device */ struct tab *search(p) struct ord *p; { register struct tab *q; for(q = &table[0] ; q->name ; q++) if(equal(p->name,q->name)) return(q); return(0); } /* * Insert an entry in configuration table */ set(p) struct tab *p; { register struct ord *q; register i; i = 0; if(p->key&BLOCK){ for(q = &border[0] ; q->name ; q++) if(equal(q->name,p->name)){ i++; q->flag =| BLOCK; } if(i == 0){ if(bextra == &border[NBFROZ-1]){ printf("Bdev Table overflow\n"); exit(1); } bextra->name = p->name; bextra->flag =| BLOCK; bextra++; } } if(p->key&CHAR){ for(q = &corder[0] ; q->name ; q++){ if(equal(q->name,p->name)){ i++; q->flag =| CHAR; } } if(i == 0){ if(cextra == &corder[NCFROZ-1]){ printf("Cdev Table overflow\n"); exit(1); } cextra->name = p->name; cextra->flag =| CHAR; cextra++; } } if(p->key&DISCP){ for(q = &dorder[0] ; q->name ; q++){ if(equal(q->name,p->name)){  i++; q->flag =| DISCP; } } } } /* * Print fixed and floating low core vectors */ low() { register addr; register struct tab *p; int ev, i, n; register *q; int hat; /* for(q= &vect[0];q<&vect[118];q++){ i = *q; if(i&&(i != RESERVED)) printf("addr %o %s\n",(q - &vect[0] + 050),(*q)->name); } */ hat = 0; for(addr=050;addr<=lowend;){ if((addr >= 0240) && flagb){ flagb = 0; puke(strb); addr =+ 014; hat = 0; continue; } if((addr >= 0300)&&flagf){ flagf = 0; puke(strc); } q = vect[(addr - 050)/4]; if(q == 0){ if(flags){ if(hat == 0) printf("\n. = %o^.\n",addr); hat++; if(flags == 1) printf("\tstray;\tbr7+%d.\n",(addr/4)%16); else printf("\ttrap;\tbr7+15.\n"); } addr =+ 4; }else{ if((i = q) == RESERVED){ printf("Bad size; collision with Reserved location\n"); } if(addr >= 0300){ if((q->key&EVEN) && (addr&07)){ printf("\t.=.+4\n"); addr =+ 4; } } printf("\n. = %o^.\n",addr); hat = 0; if(q->key & KL) {  printf(q->codea, nkl, nkl); addr =+ q->size; nkl++; } else { printf(q->codea, q->used, q->used); q->used++; addr =+ q->size; } } } } /* * Install a vector in low core map for later printing */ install(q,ad,size) struct tab *q; { register i, adr; if((q->key&INTR) == 0) return(TRUE); adr = ad; if(ad >= lowend){ if(ad >= MAXLOW) printf("%s: Vector beyond maximum range %o\n",dev,MAXLOW); else lowend = ad; } if(ad - 050 < 0){ printf("%s: Vector address %o in fixed vector area 0-050\n",dev,ad); return(FALSE); } ad = (ad - 050)/4; for(i=0;iname); return(FALSE); } } for(i=0;i= '0')&&(c <= '9')) return(TRUE); return(FALSE); } /* * Check character to see if it is alphabetic */ alpha(cc) { register char c; c = cc; if((c >= 'a')&&(c <= 'z')) return(TRUE); if((c >= 'A')&&(c <= 'Z')) return(TRUE); return(FALSE); } /* * list keyword - print list of devices added */ list() { register int *q; register addr; register i; for(addr = 050;addrname); if(q->size > 04){ printf(" <%d>",q->size/4); } printf("\n"); addr =+ q->size; continue; } addr =+ 4; } } /* * location keyword - print list of locations currently occupied */ location() { register int *q; register addr; register i; for(addr = 050;addrname); } } } /* * Look in table to see if device is known */ lookup(q) char *q; { register struct tab *p; for(p = table;p->name;p++){ if(equal(p->name,q)) return(p); } return(FALSE); } /* * Read a character */ get() { register char c; c = lastc; if(lastc){ lastc = 0; return(c); } return(getchar()); } /* * Convert an ascii string to integer */ atoi(p,base) char *p; { register n; n = 0; while(digit(*p)){ n =* base; n =+ *p++ - '0'; } return(n); } rintf("%o %s\n",addr,q->name); } } } /* * Look in table to see i# #define CHAR 01 #define BLOCK 02 #define INTR 04 #define EVEN 010 #define KL 020 #define FLOAT 040 #define DISCP 0100 /* line discipline device */ #define NULL 0 #define RESERVED 1 #define TRUE 1 #define FALSE 0 struct tab{ char *name; /* name of device recognized by mkconf */ int count; int used; int address; /* address in low core for vector */ int key; /* type of device, vect. required, etc. */ int size; /* size of low core vector */ char *codea; /* low core vector */ char *codeb; /* C interface for recieve interface */ char *codec; /* C interface for transmit interface */ char *coded; /* C interface if block device */ char *codee; /* Configuration table entry */ char *codef; /* Control switch table entry */ char *codeg; /* Error Logging */ } table[]; char *stra40[]; char *stra[]; char *strb[]; char *strc[]; char *strd[]; char *stre[]; char *strf[]; char *strg[]; char *strh[]; char *stri[]; struct ord{ char *name; struct tab *addr; int flag; }border[]; struct ord corder[]; struct ord dorder[]; struct ord std[]; int fout; int rootswap; int memflg; #define NBFROZ 8 #define NCFROZ 17 int rootdev; int swapdev; int swplo; int nswap; struct{ char lobyte; char hibyte; }; #define ROOTDEV 0 #define SWAPDEV 0 #define NCDEVSW 50 #define NBDEVSW 25 struct ord *cextra,*bextra; char *stra[]; char *strb[]; char *strc[]; char *strd[]; char *stre[]; char *strf[]; char *strg[]; char *strh[]; char *stri[]; struct ord{ char *name; struct tab *addr; int flag; }border[]; struct ord corder[]; stru# #include "mkconf.h" struct tab table[]{ "console", -1, 0, 060, CHAR+INTR+KL+DISCP, 010, "\tklin; br5\n\tklou; br5\n", ".globl\t_klrint\nklin:\tjsr\tr0,call; _klrint\n", ".globl\t_klxint\nklou:\tjsr\tr0,call; _klxint\n", "", "\t&klopen, &klclose, &klread, &klwrite, &klsgtty,", "\t&nulldev, &klmctl,", "", "mem", -1, 0, 0300, CHAR, 0, "", "", "", "", "\t&nulldev, &nulldev, &mmread, &mmwrite, &nodev,", "", "", "pc", 0, 0, 070, CHAR+INTR, 010, "\tpcin; br4\n\tpcou; br4\n", ".globl\t_pcrint\npcin:\tjsr\tr0,call; _pcrint\n", ".globl\t_pcpint\npcou:\tjsr\tr0,call; _pcpint\n", "", "\t&pcopen, &pcclose, &pcread, &pcwrite, &nodev,", "", "", "clock", -2, 0, 0100, INTR, 04, "\tkwlp; br6\n", ".globl\t_clock\n", "kwlp:\tjsr\tr0,call; _clock\n", "", "", "", "", /* * 110 unused * 114 memory parity * 120 XY plotter * 124 DR11-B */ "da", 0, 0, 0124, BLOCK+CHAR+INTR, 04, "\tdaio; br4\n", "", ".globl\t_daint\ndaio:\tjsr\tr0,call; _daint\n", "\t&daopen,\t&daclose,\t&dastrategy, \t&datab,", "\t&daopen, &daclose, &daread, &dawrite, &dasgtty,", "", "", /* * 130 AD01 * 134 AFC11 * 140 AA11 * 144 AA11 * 150-174 unused */ "lp", 0, 0, 0200, CHAR+INTR, 04, "\tlpou; br4\n", "", ".globl\t_lpint\nlpou:\tjsr\tr0,call; _lpint\n", "", "\t&lpopen, &lpclose, &nodev, &lpwrite, &nodev,", "", "", "rf", 0, 0, 0204, BLOCK+CHAR+INTR, 04, "\trfio; br5\n", ".globl\t_rfintr\n", "rfio:\tjsr\tr0,call; _rfintr\n", "\t&rfopen,\t&nulldev,\t&rfstrategy, \t&rftab,", "\t&rfopen, &nulldev, &rfread, &rfwrite, &nodev,", "", "\t&rfetab,", "hs", 0, 0, 0204, BLOCK+CHAR+INTR, 04, "\thsio; br5\n", ".globl\t_hsintr\n", "hsio:\tjsr\tr0,call; _hsintr\n", "\t&hsopen,\t&nulldev,\t&hsstrategy, \t&hstab,", "\t&hsopen, &nulldev, &hsread, &hswrite, &nodev,", "", "\t&hsetab,", /* * 210 RC */ "tc", 0, 0, 0214, BLOCK+INTR, 04, "\ttcio; br6\n", ".globl\t_tcintr\n", "tcio:\tjsr\tr0,call; _tcintr\n", "\t&tcopen,\t&tcclose,\t&tcstrategy, \t&tctab,", "", "", "\t&tcetab,", "rk", 0, 0, 0220, BLOCK+CHAR+INTR, 04, "\trkio; br5\n", ".globl\t_rkintr\n", "rkio:\tjsr\tr0,call; _rkintr\n", "\t&rkopen,\t&nulldev,\t&rkstrategy, \t&rktab,", "\t&rkopen, &nulldev, &rkread, &rkwrite, &nodev,", "", "\t&rketab,", "tm", 0, 0, 0224, BLOCK+CHAR+INTR, 04, "\ttmio; br5\n", ".globl\t_tmintr\n", "tmio:\tjsr\tr0,call; _tmintr\n", "\t&tmopen,\t&tmclose,\t&tmstrategy, \t&tmtab,", "\t&tmopen, &tmclose, &tmread, &tmwrite, &nodev,", "", "\t&tmetab,", "ht", 0, 0, 0224, BLOCK+CHAR+INTR, 04, "\thtio; br5\n", ".globl\t_htintr\n", "htio:\tjsr\tr0,call; _htintr\n", "\t&htopen,\t&htclose,\t&htstrategy, \t&httab,", "\t&htopen, &htclose, &htread, &htwrite, &nodev,", "", "\t&htetab,", "cr", 0, 0, 0230, CHAR+INTR, 04, "\tcrin; br6\n", "", ".globl\t_crint\ncrin:\tjsr\tr0,call; _crint\n", "", "\t&cropen, &crclose, &crread, &nodev, &nodev,", "", "", /* * 234 UDC11 */ "rp", 0, 0, 0254, BLOCK+CHAR+INTR, 04, "\trpio; br5\n", ".globl\t_rpintr\n", "rpio:\tjsr\tr0,call; _rpintr\n", "\t&rpopen,\t&nulldev,\t&rpstrategy, \t&rptab,", "\t&rpopen, &nulldev, &rpread, &rpwrite, &nodev,", "", "\t&rpetab,", "hp", 0, 0, 0254, BLOCK+CHAR+INTR, 04, "\thpio; br5\n", ".globl\t_hpintr\n", "hpio:\tjsr\tr0,call; _hpintr\n", "\t&hpopen,\t&nulldev,\t&hpstrategy, \t&hptab,", "\t&hpopen, &nulldev, &hpread, &hpwrite, &nodev,", "", "\t&hpetab,", /* * 260 TA11 * 264-274 unused */ /* * DM11-A */ "dn", 0, 0, 0304, CHAR+INTR, 04, "\tdnou; br5+%d.\n", "", ".globl\t_dnint\ndnou:\tjsr\tr0,call; _dnint\n", "", "\t&dnopen, &dnclose, &nodev, &dnwrite, &nodev,", "", "", "dhdm", 0, 0, 0300, INTR, 04, "\tdmin; br5+%d.\n", "", ".globl\t_dmint\ndmin:\tjsr\tr0,call; _dmint\n", "", "", "", "", "dc", 0, 0, 0300, CHAR+INTR+DISCP, 010, "\tdcin; br5+%d.\n\tdcou; br5+%d.\n", ".globl\t_dcrint\ndcin:\tjsr\tr0,call; _dcrint\n", ".globl\t_dcxint\ndcou:\tjsr\tr0,call; _dcxint\n", "", "\t&dcopen, &dcclose, &dcread, &dcwrite, &dcsgtty,", "\t&dcparam, &dcmctl,", "", "mpdc", 0, 0, 0300, CHAR+INTR, 010, "\tmpin; br5+%d.\n\tmpou; br5+%d.\n", ".globl\t_mprintr\nmpin:\tjsr\tr0,call; _mprintr\n", ".globl\t_mpxintr\nmpou:\tjsr\tr0,call; _mpxintr\n", "", "\t&mpopen, &mpclose, &mpread, &mpwrite, &mpsgtty,", "", "", "vt", 0, 0, 0300, CHAR+INTR, 04, "\tvtin; br5+%d.\n", ".globl\t_vtint\nvtin:\tjsr\tr0,call; _vtint\n", "", "", "\t&vtopen, &vtclose, &vtread, &vtwrite, &nodev,", "", "", "vtlp", 0, 0, 0300, CHAR+INTR, 04, "\tvtlpin; br5+%d.\n", ".globl\t_vtlpint\nvtlpin:\tjsr\tr0,call; _vtlpint\n", "", "", "\t&vtlpopen, &vtlpclose, &vtlpread, &nodev, &nodev,", "", "", "cm", 0, 0, 0300, CHAR+INTR, 010, "\tcmin; br5+%d.\n\tcmin; br5+%d.\n", ".globl\t_cmintr\ncmin:\tjsr\tr0,call; _cmintr\n", "", "", "\t&cmopen, &cmclose, &cmread, &cmwrite, &nodev,", "", "", "toy", 0, 0, 0320, CHAR+INTR, 010, "\ttyin; br5+%d.\n\ttyou; br5+%d.\n", ".globl\t_tyaintr\ntyin:\tjsr\tr0,call; _tyaintr\n", ".globl\t_tybintr\ntyou:\tjsr\tr0,call; _tybintr\n", "", "\t&tyopen, &nulldev, &tyread, &tywrite, &tysgtty,", "", "", "dqs", 0, 0, 0300, CHAR+INTR, 010, "\tdqsin; br5+%d.\n\tdqsou; br5+%d.\n", ".globl\t_dqsint\ndqsin:\tjsr\tr0,call; _dqsint\n", ".globl\t_dqsint\ndqsou:\tjsr\tr0,call; _dqsint\n", "", "\t&dqsopen, &dqsclose, &dqsread, &dqswrite, &nodev,", "", "", "kl", 0, 0, 0310, INTR+KL, 010, "\tklin; br5+%d.\n\tklou; br5+%d.\n", "", "", "", "", "", "", "dp", 0, 0, 0310, CHAR+INTR, 010, "\tdpin; br6+%d.\n\tdpou; br6+%d.\n", ".globl\t_dprint\ndpin:\tjsr\tr0,call; _dprint\n", ".globl\t_dpxint\ndpou:\tjsr\tr0,call; _dpxint\n", "", "\t&dpopen, &dpclose, &dpread, &dpwrite, &nodev,", "", "", /* * DR11-A+ * DR11-C+ * PA611+ * PA611+ * DT11+ * DX11+ */ "dl", 0, 0, 0300, INTR+KL+DISCP, 010, "\tklin; br4+%d.\n\tklou; br4+%d.\n", "", "", "", "", "\t&nulldev, &dlmctl,", "", "dh", 0, 0, 0300, CHAR+INTR+EVEN+DISCP, 010, "\tdhin; br5+%d.\n\tdhou; br5+%d.\n", ".globl\t_dhrint\ndhin:\tjsr\tr0,call; _dhrint\n", ".globl\t_dhxint\ndhou:\tjsr\tr0,call; _dhxint\n", "", "\t&dhopen, &dhclose, &dhread, &dhwrite, &dhsgtty,", "\t&dhparam, &dhmctl,", "", "dj", 0, 0, 0300, CHAR+INTR, 010, "\tdjin; br5+%d.\n\tdjou; br5+%d.\n", ".globl\t_djrint\ndjin:\tjsr\tr0,call; _djrint\n", ".globl\t_djxint\ndjou:\tjsr\tr0,call; _djxint\n", "", "\t&djopen, &djclose, &djread, &djwrite, &djsgtty,", "", "", "dv", 0, 0, 0300, CHAR+INTR+EVEN, 010, "\tdvin; br5+%d.\n\tdvou; br5+%d.\n", ".globl\t_dvrint\ndvin:\tjsr\tr0,call; _dvrint\n", ".globl\t_dvxint\ndvou:\tjsr\tr0,call; _dvxint\n", "", "\t&dvopen, &dvclose, &dvread, &dvwrite, &dvsgtty,", "", "", "dz", 0, 0, 0300, CHAR+INTR+EVEN, 010, "\tdzin; br5+%d.\n\tdzou; br5+%d.\n", ".globl\t_dzrint\ndzin:\tjsr\tr0,call; _dzrint\n", ".globl\t_dzxint\ndzou:\tjsr\tr0,call; _dzxint\n", "", "\t&dzopen, &dzclose, &dzread, &dzwrite, &dzsgtty,", "", "", "dmc", 0, 0, 0300, CHAR+INTR+EVEN, 010, "\tdmcin; br5+%d.\n\tdmcou; br5+%d.\n", ".globl\t_dmcrint\ndmcin:\tjsr\tr0,call; _dmcrint\n", ".globl\t_dmcxint\ndmcou:\tjsr\tr0,call; _dmcxint\n", "", "\t&dmcopen, &dmcclose, &dmcread, &dmcwrite, &dmcsgtty,", "", "", /* * GT40 * LPS+ * VT20 */ "null", 0, 0, 0, CHAR+BLOCK, 0, "", "", "", "\t&nodev,\t\t&nodev,\t\t&nodev,\t\t0,", "\t&nodev, &nodev, &nodev, &nodev, &nodev,",  "\t&nodev, &nodev,", "", "parity", 0, 0, 0114, INTR, 04, "\ttrap; br7+10.\t\t/ 11/70 parity\n", "", "", "", "", "", "", /* * Spider */ "tiu", 0, 0, 0174, INTR+CHAR, 04, "\ttiuio; br6\n", ".globl\t_tiuintr\ntiuio:\tjsr\tr0,call; _tiuintr", "", "", "\t&tiuopen, &tiuclose, &tiuread, &tiuwrite, &snstat,", "", "", /* * Time of day clock */ "tdck", 0, 0, 0, CHAR, 0, "", "", "", "", "\t&nulldev, &nulldev, &nulldev, &nulldev, &tdsgtty,", "", "", /* * Indirect teletype driver */ "sys", 0, 0, 0, CHAR, 0, "", "", "", "", "\t&syopen, &nulldev, &syread, &sywrite, &sysgtty,", "", "", "du", 0, 0, 0300, CHAR+INTR, 010, "\tduin; br5+%d.\n\tduou; br5+%d.\n", ".globl\t_durint\nduin:\tjsr\tr0,call; _durint\n", ".globl\t_duxint\nduou:\tjsr\tr0,call; _duxint\n", "", "\t&duopen, &duclose, &duread, &duwrite, &nodev,", "", "", 0 }; char *stra40[] { "/copyright 1974 Bell Telephone Laboratories Inc.", "/low core", "", "br4 = 200", "br5 = 240", "br6 = 300", "br7 = 340", "", ". = 0^.", "\tbr\t1f", "\t4", "", "/ trap vectors", "\ttrap; br7+0.\t\t/ bus error", "\ttrap; br7+1.\t\t/ illeagle instruction", "\ttrap; br7+2.\t\t/ bpt-trace trap", "\ttrap; br7+3.\t\t/ iot trap", "\ttrap; br7+4.\t\t/ power fail", "\ttrap; br7+5.\t\t/ emulator trap", "\ttrap; br7+6.\t\t/ system entry", "", ". = 40^.", ".globl\tstart, dump", "1:\tjmp\tstart", "\tjmp\tdump", "", 0, }; char *stra[] { "/ Copyright 1974 Bell Telephone Laboratories Inc", "/ low core", "", ".data", "br4 = 200", "br5 = 240", "br6 = 300", "br7 = 340", "", ". = 0^.", "\tbr\t1f", "\t4", "", "/ trap vectors", "\ttrap; br7+0.\t\t/ bus error", "\ttrap; br7+1.\t\t/ illegal instruction", "\ttrap; br7+2.\t\t/ bpt-trace trap", "\ttrap; br7+3.\t\t/ iot trap", "\ttrap; br7+4.\t\t/ power fail", "\ttrap; br7+5.\t\t/ emulator trap", "\ttrap; br7+6.\t\t/ system entry", "", ". = 40^.", ".globl\tstart, dump", "1:\tjmp\tstart", "\tjmp\tdump", "", 0, }; char *strb[] { "", ". = 240^.", "\ttrap; br7+7.\t\t/ programmed interrupt", "\ttrap; br7+8.\t\t/ floating point", "\ttrap; br7+9.\t\t/ segmentation violation", 0 }; char *strc[] { "", "/ floating vectors", 0, }; char *strd[] { "", "//////////////////////////////////////////////////////", "/\t\tinterface code to C", "//////////////////////////////////////////////////////", "", ".globl\tcall, trap", 0 }; char *stre[] { "#", "#include \"../head/param.h\"", "", "/*", " *\tCopyright 1974 Bell Telephone Laboratories Inc", " */", "", "/*", " *\tFrozen Configuration Table - New devices may be", " *\tadded to the end of the tables only!", " *\tblock order - rk,rp,rf,tm,tc,hp,ht,hs,0", " *\tcharacter order - kl,pc,lp,dc,dh,dp,dj,dn,mem,rk,rf,rp,tm,", " *\t\t\thp,ht,hs,sys,0", " */", "int\t(*bdevsw[])()", "{", 0, }; char *strf[] { "\t0", "};", "", "int\t(*cdevsw[])()", "{", 0, }; char *strg[] { "\t0", "};", "", "int\t(*ctlsw[])()", "{", 0, }; char *strh[] { "\t0", "};", "", "int\t(*linesw[])() {", "&ttopen, &ttclose, &ttread, &ttwrite, &ttyinput,&ttxmtd, &ttmt, &ttstty,", "\t0", "};", 0, }; char *stri[]{ "int sysparam[]{", "\tNPROC,", "\tNTEXT,", "\tNINODE,", "\tNFILE,", "\tNBUF,", "\tNMOUNT,", "\tNCLIST,", "\t0", "};", 0 }; struct ord border[NBDEVSW]{ "rk", 0, 0, "rp", 0, 0, "rf", 0, 0, "tm", 0, 0, "tc", 0, 0, "hp", 0, 0, "ht", 0, 0, "hs", 0, 0, 0 }; struct ord corder[NCDEVSW]{ "console", 0, 0, "pc", 0, 0, "lp", 0, 0, "dc", 0, 0, "dh", 0, 0,  "dp", 0, 0, "dj", 0, 0, "dn", 0, 0, "mem", 0, 0, "rk", 0, 0, "rf", 0, 0, "rp", 0, 0, "tm", 0, 0, "hp", 0, 0, "ht", 0, 0, "hs", 0, 0, "sys", 0, 0, 0 }; struct ord dorder[]{ "console", 0, 0, "dl", 0, 0, "dc", 0, 0, "dh", 0, 0, 0 }; struct ord std[]{"null",0,0}; int rootswap -2; int memflg -2; int rootdev ROOTDEV; int swapdev SWAPDEV; int swplo 4000; int nswap 872; struct ord *bextra &border[NBFROZ]; struct ord *cextra &corder[NCFROZ]; 0, "pc", 0, 0, "lp", 0, 0, "dc", 0, 0, "dh", 0, 0, w e 777 ]@ȥ-X5P@7 y@* @  @&  7%=  tU @k  7 0(   4  0& z %  4  @& z % D& z %  4 <e%B  7  7p 7 j ^ R%L F p 4 F F  5 & %e  %     7 7 7    F5 N   T e  F5 N  # e  F5 N ' 15 e  FE&E9 %pEg&EU %Rp D   F &    e   7 %    ww N @e5ww 5 5 @ 0 %7b5  n  % A‹ wB¥ ¥ 5       7 @ p     %_%( _ _%_%_Bj_b P < 7B_(   _%  h%   V5 %    5 %+w5 5  pf @5 RV 7 B7 > 0z ew_  5 %    5 %_6w5 5  f @5_6 p'_6 ewUNT *%Z_.   l_65    5_w_ %_  _6   7_  R_|  _b  P_H 6  5 5      5 5 _6e   @ 5@   5 @ 5@  @ &  55_ 85_6%@l% K_6 5 5 9 AAmsp lAsp Amu35Y NeEx_6 f z % _ u-sm 4 _w dDCԢӋwL w D  4e   4e   4e ww  f we  w  @5,N&  Ue  %*  rnUeb@5,N&  Ue  %`&   Ue@5@N&  U@e ww 5 (_l 7  Fe 5 _l %%  7  Fe r ( `"  %B r rN  e@5% % 3 5 e 5 5 %l  % l -_j ww @5wnC-~% V! %w\@e N2E % Ae r5 2 r@m & r@m %aw r@m a eeD-  r@m peD-w |Dĥ0ĥ9wd w \Dĥa ĥzĥZĥA w2w .(4 +% %%  r  m e r e-ww (e r %  %e-wfw b N& wFe  w 6ĝH D7 >w" w  upD@e` @  want`L%c: Not an option low core ends at 0777! End of low core - %o %s: not an address! consoleconsoleclockclockmemmeml.sCan't create l.s %s%s .globl _stray stray: jsr r0,call; _stray c.cCan't create c.c /*%2.2d*/%s %s /*%2.2d*/%s %s /*%2.2d*/%s %s int rootdev {(%d<<8)|%d}; int swapdev {(%d<<8)|%d}; int swplo %d; int nswap %d; int *errtabs[]{ %s 0}; End of low core %o %s 4570parity3440Which processor? 40? 34? 45? 70? rootroot: Arg count! root: %s Unknown device? root: %s Minor device number out of range root: %s Not in Block Device Table root: %s Device not in Configuration Table! swapswap: Arg count! swap: %s Unknown device? swap: %s Minor device number out of range swap: %s not in Block Device Table swap: %s Device not in Configuration Table! swploswplo: Arg count swplo: %s swap offset? Swap offset cannot be zero! nswapnswap: Arg count nswap: %s number of swap blocks? listlocationerrorlogqquit%s: Unknown device! Vectors at double word boundary only! %s: no more, no less %s: only one Even address required for %s! Specify %o instead Bdev Table overflow Cdev Table overflow . = %o^. stray; br7+%d. trap; br7+15. Bad size; collision with Reserved location .=.+4 . = %o^. %s: Vector beyond maximum range %o %s: Vector address %o in fixed vector area 0-050 %s: Vector at %o reserved %s: Vector at %o occupied by %s %o Reserved %o %s <%d> %o Reserved %o %s 8(8X(8hx))99IY)(H 8 I H 8 I I I I I I I I I I )I I 9)I )I I I I 9I I I 9I I I I II I I I YI I I )I I I I I I H H H yyyyiiii8H _table _stra40 _stra _strb _strc _strd _stre _strf _strg _strh _stri _border _corder _dorder _std _fout _rootswa _memflg _rootdev _swapdev _swplo _nswap _cextra _bextra _z _vect _flagf _flagb _flagm _flags _nkl _lastc#_lowend#_dev _log _main"L10002L10003 L9`L16L17L7L~maincsv ipargcqnsyargvapevL2L3L200018L10004DL8*_printf _exit _digit"L10_atoi"L10000L11L12=L13UL15kL18L19_lookup"_set"4 _install"z L20L21L22L23L20003ZL27n_input"p_flush L29_creat L30L31L32L20004_puke"F_low"8 L34L35L20006L37L39L40 L41L42_close _init" _search" L43L44pL45L46L20010L49L50L51 L20008L53L54L20014L57L58L59L20012L61#L62bL20018&L65'L66LL671L20016XL695L709L71UL72pL73L74L75L76L77L20020L79L81L82L838L84cret ~pukeFcsL86\L20022NL88_lp _line d_arg ~inputpindcfipqnostaddrvixspcountL20024L93_get"L946L95L89_alpha"L97L100L20027L105 L20033L20051L122_equal" L20053L141L142L144L145L20034L20049L110L113L114L115L117L10006L118L119L121L20055L125"L126L127>L128L200366L129\L10008jL130tL131+L132L133L135L136L137VL138L139zL146L147L148&L100104L149@L150L151TL152L154L155L156L157L158'L160TL161L162L163ZL164L165lL166 L167L169L170fL1716L172L173PL174L176L177_list"L179L180_locatio"JL182L183L185L10011L186L140L188 L189$ L190> L20029. L195L192: L191V L196z L197 L199L200 L2015L202 L203KL204 L205 L20032 L208& L200302 L210d L212YL213x~equal abpqL216 L217 L215 ~init pqL220 L20057 L223 L20059 L226 L20061 ~search pqL230, L20063 L232( L229$ ~set4 ipqL235 L236h L20065L L238d L241 L242L243 L244 L20067 L246 L249 L250L2344 L2520 L20069 L254, ~low8 hatiaddrpnqevL257l L20071L L259p L20073j L260 L261 L262 L263 L264L265 L266L268L270 L271L272 L274L275L276R ~installz adriqsizeadL279 L20078 L278 L280 L281 L282!L284 L285EL20081 L20079 L286VL20075 L288RL290*L291wL293L294xL20077`~digitcccL298L297~alphacccL300L20082L299L20084L301~listiaddrqL303@L20086L307L20091<L20088L308L309L310L311L20090(~locatioJiaddrqL313L20093TL315L317~L318L319~lookuppqL321L20095L323L320~getcL326L325_getchar ~atoipbasenL328L20097~listiaddrqL303@L20086L307"0U$OP8*UV@T 2 l m n q } ~   F } ~  $ % / 2 > N j   < = G J V f  ) S   'CmJKUXhi   E1\-Z[   $STU=j$PQ./fghTkM!"[uvy()* -Lw +VW RSTYZ[\{L| 789qrsxyz{|Itu"%&5Pv  &3=>oz{ ,Fb%MNab   M Q R U !-!1!C!E!H!K!L!^!`!c!f!g!x!z!}!!!!!!!!" """""+"4"7":"="@"C"F"I"L"O"R"Z"]"`"c"f"i"l"o"s"v"y"|""""""""""hconsole klin; br5 klou; br5 .globl _klrint klin: jsr r0,call; _klrint .globl _klxint klou: jsr r0,call; _klxint &klopen, &klclose, &klread, &klwrite, &klsgtty, &nulldev, &klmctl,mem &nulldev, &nulldev, &mmread, &mmwrite, &nodev,pc pcin; br4 pcou; br4 .globl _pcrint pcin: jsr r0,call; _pcrint .globl _pcpint pcou: jsr r0,call; _pcpint &pcopen, &pcclose, &pcread, &pcwrite, &nodev,clock kwlp; br6 .globl _clock kwlp: jsr r0,call; _clock da daio; br4 .globl _daint daio: jsr r0,call; _daint &daopen, &daclose, &dastrategy, &datab, &daopen, &daclose, &daread, &dawrite, &dasgtty,lp lpou; br4 .globl _lpint lpou: jsr r0,call; _lpint &lpopen, &lpclose, &nodev, &lpwrite, &nodev,rf rfio; br5 .globl _rfintr rfio: jsr r0,call; _rfintr &rfopen, &nulldev, &rfstrategy, &rftab, &rfopen, &nulldev, &rfread, &rfwrite, &nodev, &rfetab,hs hsio; br5 .globl _hsintr hsio: jsr r0,call; _hsintr &hsopen, &nulldev, &hsstrategy, &hstab, &hsopen, &nulldev, &hsread, &hswrite, &nodev, &hsetab,tc tcio; br6 .globl _tcintr tcio: jsr r0,call; _tcintr &tcopen, &tcclose, &tcstrategy, &tctab, &tcetab,rk rkio; br5 .globl _rkintr rkio: jsr r0,call; _rkintr &rkopen, &nulldev, &rkstrategy, &rktab, &rkopen, &nulldev, &rkread, &rkwrite, &nodev, &rketab,tm tmio; br5 .globl _tmintr tmio: jsr r0,call; _tmintr &tmopen, &tmclose, &tmstrategy, &tmtab, &tmopen, &tmclose, &tmread, &tmwrite, &nodev, &tmetab,ht htio; br5 .globl _htintr htio: jsr r0,call; _htintr &htopen, &htclose, &htstrategy, &httab, &htopen, &htclose, &htread, &htwrite, &nodev, &htetab,cr crin; br6 .globl _crint crin: jsr r0,call; _crint &cropen, &crclose, &crread,  &nodev, &nodev,rp rpio; br5 .globl _rpintr rpio: jsr r0,call; _rpintr &rpopen, &nulldev, &rpstrategy, &rptab, &rpopen, &nulldev, &rpread, &rpwrite, &nodev, &rpetab,hp hpio; br5 .globl _hpintr hpio: jsr r0,call; _hpintr &hpopen, &nulldev, &hpstrategy, &hptab, &hpopen, &nulldev, &hpread, &hpwrite, &nodev, &hpetab,dn dnou; br5+%d. .globl _dnint dnou: jsr r0,call; _dnint &dnopen, &dnclose, &nodev, &dnwrite, &nodev,dhdm dmin; br5+%d. .globl _dmint dmin: jsr r0,call; _dmint dc dcin; br5+%d. dcou; br5+%d. .globl _dcrint dcin: jsr r0,call; _dcrint .globl _dcxint dcou: jsr r0,call; _dcxint &dcopen, &dcclose, &dcread, &dcwrite, &dcsgtty, &dcparam, &dcmctl,mpdc mpin; br5+%d. mpou; br5+%d. .globl _mprintr mpin: jsr r0,call; _mprintr .globl _mpxintr mpou: jsr r0,call; _mpxintr &mpopen, &mpclose, &mpread, &mpwrite, &mpsgtty,vt vtin; br5+%d. .globl _vtint vtin: jsr r0,call; _vtint &vtopen, &vtclose, &vtread, &vtwrite, &nodev,vtlp vtlpin; br5+%d. .globl _vtlpint vtlpin: jsr r0,call; _vtlpint &vtlpopen, &vtlpclose, &vtlpread, &nodev, &nodev,cm cmin; br5+%d. cmin; br5+%d. .globl _cmintr cmin: jsr r0,call; _cmintr &cmopen, &cmclose, &cmread, &cmwrite, &nodev,toy tyin; br5+%d. tyou; br5+%d. .globl _tyaintr tyin: jsr r0,call; _tyaintr .globl _tybintr tyou: jsr r0,call; _tybintr &tyopen, &nulldev, &tyread, &tywrite, &tysgtty,dqs dqsin; br5+%d. dqsou; br5+%d. .globl _dqsint dqsin: jsr r0,call; _dqsint .globl _dqsint dqsou: jsr r0,call; _dqsint &dqsopen, &dqsclose, &dqsread, &dqswrite, &nodev,kl klin; br5+%d. klou; br5+%d. dp dpin; br6+%d. dpou; br6+%d. .globl _dprint dpin: jsr r0,call; _dprint .globl _dpxint dpou: jsr r0,call; _dpxint &dpopen, &dpclose, &dpread, &dpwrite, &nodev,dl klin; br4+%d. klou; br4+%d. &nulldev, &dlmctl,dh dhin; br5+%d. dhou; br5+%d. .globl _dhrint dhin: jsr r0,call; _dhrint .globl _dhxint dhou: jsr r0,call; _dhxint &dhopen, &dhclose, &dhread, &dhwrite, &dhsgtty, &dhparam, &dhmctl,dj djin; br5+%d. djou; br5+%d. .globl _djrint djin: jsr r0,call; _djrint .globl _djxint djou: jsr r0,call; _djxint &djopen, &djclose, &djread, &djwrite, &djsgtty,dv dvin; br5+%d. dvou; br5+%d. .globl _dvrint dvin: jsr r0,call; _dvrint .globl _dvxint dvou: jsr r0,call; _dvxint &dvopen, &dvclose, &dvread, &dvwrite, &dvsgtty,dz dzin; br5+%d.  dzou; br5+%d. .globl _dzrint dzin: jsr r0,call; _dzrint .globl _dzxint dzou: jsr r0,call; _dzxint &dzopen, &dzclose, &dzread, &dzwrite, &dzsgtty,dmc dmcin; br5+%d. dmcou; br5+%d. .globl _dmcrint dmcin: jsr r0,call; _dmcrint .globl _dmcxint dmcou: jsr r0,call; _dmcxint &dmcopen, &dmcclose, &dmcread, &dmcwrite, &dmcsgtty,null &nodev, &nodev, &nodev, 0, &nodev, &nodev, &nodev, &nodev, &nodev, &nodev, &nodev,parity trap; br7+10. / 11/70 parity tiu tiuio; br6 .globl _tiuintr tiuio: jsr r0,call; _tiuintr &tiuopen, &tiuclose, &tiuread, &tiuwrite, &snstat,tdck &nulldev, &nulldev, &nulldev, &nulldev, &tdsgtty,sys &syopen, &nulldev, &syread, &sywrite, &sysgtty,du duin; br5+%d. duou; br5+%d. .globl _durint duin: jsr r0,call; _durint .globl _duxint duou: jsr r0,call; _duxint &duopen, &duclose, &duread, &duwrite, &nodev,/copyright 1974 Bell Telephone Laboratories Inc./low corebr4 = 200br5 = 240br6 = 300br7 = 340. = 0^. br 1f 4/ trap vectors trap; br7+0. / bus error trap; br7+1. / illeagle instruction trap; br7+2. / bpt-trace trap trap; br7+3. / iot trap trap; br7+4. / power fail trap; br7+5. / emulator trap trap; br7+6. / system entry. = 40^..globl start, dump1: jmp start jmp dump/ Copyright 1974 Bell Telephone Laboratories Inc/ low core.databr4 = 200br5 = 240br6 = 300br7 = 340. = 0^. br 1f 4/ trap vectors trap; br7+0. / bus error trap; br7+1. / illegal instruction trap; br7+2. / bpt-trace trap trap; br7+3. / iot trap trap; br7+4. / power fail trap; br7+5. / emulator trap trap; br7+6. / system entry. = 40^..globl start, dump1: jmp start jmp dump. = 240^. trap; br7+7. / programmed interrupt trap; br7+8. / floating point trap; br7+9. / segmentation violation/ floating vectors/////////////////////////////////////////////////////// interface code to C//////////////////////////////////////////////////////.globl call, trap##include "../head/param.h"/* * Copyright 1974 Bell Telephone Laboratories Inc *//* * Frozen Configuration Table - New devices may be * added to the end of the tables only! * block order - rk,rp,rf,tm,tc,hp,ht,hs,0 * character order - kl,pc,lp,dc,dh,dp,dj,dn,mem,rk,rf,rp,tm, * hp,ht,hs,sys,0 */int (*bdevsw[])(){ 0};int (*cdevsw[])(){ 0};int (*ctlsw[])(){ 0};int (*linesw[])() {&ttopen, &ttclose, &ttread, &ttwrite, &ttyinput,&ttxmtd, &ttmt, &ttstty, 0};int sysparam[]{ NPROC, NTEXT, NINODE, NFILE, NBUF, NMOUNT, NCLIST, 0};rkrprftmtchphthsconsolepclpdcdhdpdjdnmemrkrfrptmhphthssysconsoledldcdhnull_table#_stra40#_stra#,_strb#d_strc#p_strd#v_stre#_strf#_strg#_strh#_stri#_border#_corder#z_dorder#_std#_fout _rootswa#_memflg#_rootdev#_swapdev#_swplo#_nswap#_cextra#_bextra#L1L2L3L4$L5OL6PL7L8L9L10L11L12L13L14L15L16L17L18L19L20*L21UL22VL23L24L25L26L27L28L29L30L31L32L33L34L35L36L37 L382 L39l L40m L41n L42q L43} L44~ L45 L46 L47 L48 L49 L50 L51 L52 L53 L54F L55} L56~ L57 L58 L59 L60 L61 L62 L63$ L64% L65/ L662 L67> L68N L69j L70 L71 L72 L73 L74 L75 L76 L77 L78 L79< L80= L81G L82J L83V L84f L85 L86 L87 L88 L89 L90 L91 L92 L93) L94S L95 L96 L97 L98 L99 L100 L101 L102 L103L104L105L106 L107L108'L109CL110mL111L112L113L114L115L116L117L118L119JL120KL121UL122XL123hL124iL125L126L127L128L129L130L131L132L133 L134 L135 L136L137L138L1391L140\L141L142L143L144L145L146L147L148-L149ZL150[L151L152L153L154L155L156L157L158L159 L160 L161 L162L163$L164SL165TL166UL167L168L169L170L171L172L173L174L175L176L177L178L179=L180jL181L182L183L184L185L186L187L188$L189PL190QL191L192L193L194L195L196L197L198L199L200L201L202L203L204L205.L206/L207fL208gL209hL210kL211L212L213L214L215L216L217L218L219L220L221!L222"L223[L224uL225vL226yL227L228L229L230L231(L232)L233*L234-L235LL236wL237L238L239L240L241L242L243L244+L245VL246WL247L248L249L250L251L252L253L254L255RL256SL257TL258YL259ZL260[L261\L262{L263L264L265L266L267L268L269L270L271L272L273L274L275 L2767L2778L2789L279qL280rL281sL282xL283yL284zL285{L286|L287L288L289L290L291L292L293L294L295L296L297L298L299L300IL301tL302uL303L304L305L306L307L308L309L310L311L312L313L314L315"L316%L317&L3185L319PL320vL321L322L323L324L325 L326 L327L328&L3293L330=L331>L332oL333zL334{L335L336L337L338L339L340L341L342L343L344L345L346L347 L348,L349FL350bL351L352L353L354L355L356L357L358L359L360L361L362%L363ML364NL365aL366bL367L368L369L370L371L372L373 L374 L375 L376M L377Q L378R L379U L380 L381 L382 L383!L384-!L3851!L386C!L387E!L388H!L389K!L390L!L391^!L392`!L393c!L394f!L395g!L396x!L397z!L398}!L399!L400!L401!L402!L403!L404!L405!L406"L407 "L408"L409"L410""L411+"L4124"L4137"L414:"L415="L416@"L417C"L418F"L419I"L420L"L421O"L422R"L423Z"L424]"L425`"L426c"L427f"L428i"L429l"L430o"L431s"L432v"L433y"L434|"L435"L436"L437"L438"L439"L440"L441"L442"L443"!L402!L403!L404!L405!L406"L407 "L408"L409"L410""L411+"L4124"L4137"L414:"L415="L416@"L417C"/ format RK03/05 disk packs rkda = 177412 5 mov $203.*2,r4 clr r3 1: mov $rkda+2,r0 mov r3,-(r0) mov $buf,-(r0) mov $-12.*256.,-(r0) mov $6003,-(r0) 2: tstb (r0) bge 2b tst (r0) blt 1f add $20,r3 dec r4 bne 1b rts pc 1: jsr pc,4(r5) ; .even rts pc buf: .=.+2 "L443"!L402!L403!L404!L405!L406"L407 "L408"L409"L410""L411+"L4124"L4137"L414:"L415="L416@"L417C"/ tape boot program to load and transfer / to a 'tp' entry / entry is made by jsr pc,*$0 / so return can be rts pc / jsr pc,(r5) is putc / jsr pc,2(r5) is getc / jsr pc,4(r5) is mesg core = 24. .mt. = 0 .tc. = 0 .tu. = 1 .. = [core*2048.]-512. start: mov $..,sp mov $name,r4 mov sp,r1 cmp pc,r1 bhis 2f clr r0 cmp (r0),$407 bne 1f mov $20,r0 1: mov (r0)+,(r1)+ cmp r1,$end blo 1b jmp (sp) 2: jsr pc,rew mov $tvec,r5 mov $'=,r0 jsr pc,(r5) 2: mov r4,r1 1: jsr pc,2(r5) cmp r0,$'\n beq 1f cmp r0,$'@ beq 2b movb r0,(r1)+ cmp r0,$'# bne 1b sub $2,r1 cmp r1,r4 blo 2b br 1b 1: clrb (r1) cmp r1,r4 blos start mov $1,tapa mov $-6144.,wc jsr pc,taper clr r1 1: mov r1,r2 mov r4,r0 2: cmpb (r0)+,(r1) bne 2f tstb (r1)+ bne 2b br 1f 2: mov r2,r1 add $64.,r1 cmp r1,$12288. blo 1b jsr pc,rew br start 1: mov 44.(r2),tapa mov 38.(r2),r0 inc r0 clc ror r0 neg r0 mov r0,wc clr r0 1: clr (r0)+ cmp r0,sp blo 1b jsr pc,taper jsr pc,rew clr r0 cmp (r0),$407 / unix a.out? bne 2f 1: mov 20(r0),(r0)+ cmp r0,sp blo 1b 2: jsr pc,*$0 br start .if .mt. mts = 172520 mtc = 172522 mtbrc = 172524 mtcma = 172526 taper: clr mtma cmp mtapa,tapa beq 1f bhi 2f jsr pc,rrec br taper 2: jsr pc,rew br taper 1: mov wc,r1 1: jsr pc,rrec add $256.,r1 bmi 1b rts pc rrec: bit $2,*$mts bne rrec tstb *$mtc bge rrec mov $-512.,*$mtbrc mov mtma,*$mtcma mov $60003,*$mtc 1: tstb *$mtc bge 1b tst *$mtc bge 1f mov $-1,*$mtbrc mov $60013,*$mtc br rrec 1: add $512.,mtma inc mtapa rts pc rew: mov $60017,*$mtc clr mtapa rts pc .endif .if .tu. tucs1 = 172440 tuwc = 172442 tuba = 172444 tufc = 172446 tucs2 = 172450 tuds = 172452 tutc = 172472 taper: clr mtma cmp mtapa,tapa beq 1f bhi 2f jsr pc,rrec br taper 2: jsr pc,rew br taper 1: mov wc,r1 1: jsr pc,rrec add $256.,r1 bmi 1b rts pc rrec: bit $020000,*$tuds bne rrec tstb *$tucs1 bge rrec mov $-256.,*$tuwc mov mtma,*$tuba mov $071,*$tucs1 1: tstb *$tucs1 bge 1b bit $040000,*$tucs1 beq 1f mov $040,*$tucs2 mov $-1,*$tufc mov $033,*$tucs1 br rrec 1: add $512.,mtma inc mtapa rts pc rew: mov $040,*$tucs2 mov $07,*$tucs1 clr mtapa rts pc .endif .if .tc. tcdt = 177350 tccm = 177342 taper: mov $tcdt,r0 mov $tccm,r1 for: mov $3,(r1) / rbn for 1: tstb (r1) bge 1b tst (r1) blt rev cmp tapa,(r0) beq rd bgt for rev: mov $4003,(r1) / rbn bac 1: tstb (r1) bge 1b tst (r1) blt for mov (r0),r2 add $5,r2 cmp tapa,r2 blt rev br for rd: clr -(r0) / bus addr mov wc,-(r0) / wc mov $5,-(r0) / read 1: tstb (r1) bge 1b tst (r1) blt taper rts pc rew: mov $4003,tccm rts pc .endif tvec: br putc br getc br mesg tks = 177560 tkb = 177562 getc: mov $tks,r0 inc (r0) 1: tstb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1f cmp r0,$'Z bhi 1f add $40,r0 1: cmp r0,$'\r bne putc mov $'\n,r0 tps = 177564 tpb = 177566 putc: tstb tps bge putc cmp r0,$'\n bne 1f mov $'\r,r0 jsr pc,(r5) mov $'\n+200,r0 jsr pc,(r5) clr r0 jsr pc,(r5) mov $'\n,r0 rts pc 1: mov r0,tpb rts pc mesg: movb *(sp),r0 beq 1f jsr pc,(r5) inc (sp) br mesg 1: add $2,(sp) bic $1,(sp) rts pc end: tapa: .=.+2 mtapa: .=.+2 mtma: .=.+2 wc: .=.+2 name: .=.+32. 0 inc (r0) 1: tstb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1f cmp r0,$'Z bhi 1f add $40,r0 1: cmp r0,$'\r bne putc mov $'\n,r0 tps = 177564 tpb = 177566 putc: tstb tps bge putc cmp r0,$'\n bne 1f mov $'\r,r0 jsr pc,(r5) mov $'\n+200,r0 jsr pc,(r5) clr r0 jsr pc,(r5) mov $'\n,r0 rts/ disk boot program to load and transfer / to a unix entry / entry is made by jsr pc,*$0 / so return can be rts pc core = 24. .. = [core*2048.]-512. start: mov $..,sp mov sp,r1 cmp pc,r1 bhis 2f reset clr r0 cmp (r0),$407 bne 1f mov $20,r0 1: mov (r0)+,(r1)+ cmp r1,$end blo 1b jmp (sp) 2: mov $inod,r0 1: clr (r0)+ cmp r0,sp blo 1b jsr pc,getc cmp r0,$'k bne 3f mov $rkblk,r0 br 1f 3: cmp r0,$'p bne 2b mov $rpblk,r0 1: mov r0,rxblk mov $'\n,r0 jsr pc,putc mov $names,r1 1: mov r1,r2 2: jsr pc,getc cmp r0,$'\n beq 1f cmp r0,$'/ beq 3f movb r0,(r2)+ br 2b 3: cmp r1,r2 beq 2b add $14.,r1 br 1b 1: mov $names,r1 mov $1,r0 1: clr bno jsr pc,iget tst (r1) beq 1f 2: jsr pc,rmblk br start mov $buf,r2 3: mov r1,r3 mov r2,r4 add $16.,r2 tst (r4)+ beq 5f 4: cmpb (r3)+,(r4)+ bne 5f cmp r4,r2 blo 4b mov -16.(r2),r0 add $14.,r1 br 1b 5: cmp r2,$buf+512. blo 3b br 2b 1: clr r1 1: jsr pc,rmblk br 1f mov $buf,r2 2: mov (r2)+,(r1)+ cmp r2,$buf+512. blo 2b br 1b 1: clr r0 cmp (r0),$407 bne 2f 1: mov 20(r0),(r0)+ cmp r0,sp blo 1b 2: jsr pc,*$0 br start iget: add $31.,r0 mov r0,r5 ash $-4.,r0 jsr pc,rblk bic $!17,r5 ash $5.,r5 add $buf,r5 mov $inod,r4 1: mov (r5)+,(r4)+ cmp r4,$addr+16. blo 1b rts pc rmblk: add $2,(sp) mov bno,r0 inc bno bit $LRG,mode bne 1f asl r0 mov addr(r0),r0 bne rblk 2: sub $2,(sp) rts pc 1: clr -(sp) movb r0,(sp) clrb r0 swab r0 asl r0 mov addr(r0),r0 beq 2b jsr pc,rblk mov (sp)+,r0 asl r0 mov buf(r0),r0 beq 2b rblk: mov r1,-(sp) mov r0,r1 clr r0 jmp *rxblk rpda = 176724 rpblk: div $10.,r0 mov r1,-(sp) mov r0,r1 clr r0 div $20.,r0 bisb r1,1(sp) mov $rpda,r1 mov (sp)+,(r1) br 1f rkda = 177412 rkblk: div $12.,r0 ash $4.,r0 bis r1,r0 mov $rkda+2,r1 1: mov r0,-(r1) mov $buf,-(r1) mov $-256.,-(r1) mov $5,-(r1) 1: tstb (r1) bge 1b mov (sp)+,r1 rts pc tks = 177560 tkb = 177562 getc: mov $tks,r0 inc (r0) 1: tstb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1f cmp r0,$'Z bhi 1f add $40,r0 1: cmp r0,$'\r bne putc mov $'\n,r0 tps = 177564 tpb = 177566 putc: tstb tps bge putc cmp r0,$'\n bne 1f mov $'\r,r0 jsr pc,putc mov $'\n+200,r0 jsr pc,putc clr r0 jsr pc,putc mov $'\n,r0 rts pc 1: mov r0,tpb rts pc end: inod = ..-1024. mode = inod addr = inod+8. buf = inod+32. bno = buf+514. rxblk = bno+2 names = rxblk+2 LRG = 10000 reset = 5 7560 tkb = 177562 getc: mov $tks,r0 inc (r0) 1: tstb (r0) bge 1b mov tkb,r0 bic $!177,r0 cmp r0,$'A blo 1# /* MANIFEST CONSTANT DEFINITIONS */ # define NTBASE 010000 /* internal codes for error and accept actions */ # define ERRCODE 8190 # define ACCEPTCODE 8191 # define errfileno 1 /* file number for erros and reduction message */ # define _tbitset 6 /* 16*_tbitset - 1 >= _nterms */ extern int tbitset; /* number of wds of lookahead vector */ extern int nolook; /* flag to turn off lookahed computations */ struct looksets { int lset[ _tbitset ]; } ; struct item { int *pitem; struct looksets *look; } ; /* output actions */ # define ERRACT 0 # define TESTACT 4096 # define SHIFTACT 8192 # define REDUCACT 12288 # define ACCEPTACT 16384 # define _REGISTER register extern int nstate ; /* number of states */ extern struct item *pstate[]; /* pointers to the descriptions of the states */ extern int apstate[]; /* index to actions in amem by state */ extern int actsiz; /* size of the action table array */ extern int tystate[]; /* contains type information about the states */ /* 0 = simple state, completely generated 1 = state awaiting generation 2 = state with an empty production in closure */ extern int stsize ; /* maximum number of states, at present */ extern int memsiz ; /* maximum size for productions and states */ extern int mem0[] ; /* added production */ extern int *mem ; extern int amem[]; /* action table storage */ extern int actsiz; /* action table size */ extern int memact ; /* next free action table position */ extern int nprod ; /* number of productions */ extern int *prdptr[]; /* pointers to descriptions of productions */ extern int prdlim; /* the number of productions allowed */ extern int levprd[] ; /* contains production levels to break conflicts */ /* last two bits code associativity: 0 = no definition 1 = left associative 2 = binary 3 = right associative bit 04 is 1 if the production has an action the high 13 bits have the production level */ extern int nterms ; /* number of terminals */ extern int nerrors; /* number of errors */ extern int fatfl; /* if on, error is fatal */ /* the ascii representations of the terminals */ extern int extval; /* start of output values */ extern struct sxxx1 {char *name; int value;} trmset[]; extern char cnames[]; extern int cnamsz; extern char *cnamp; extern int maxtmp ; /* the size of the temp arrays */ /* temporary vectors, indexable by states, terms, or nterms */ extern int temp1[]; extern int temp2[]; extern int trmlev[]; /* vector with the precedence of the terminals */ /* The levels are the same as for levprd, but bit 04 is always 0 */ /* the ascii representations of the nonterminals */ extern struct sxxx2 { char *name; } nontrst[]; extern int indgo[]; /* index to the stored goto table */ extern int ***pres; /* vector of pointers to the productions yielding each nonterminal */ extern struct looksets **pfirst; /* vector of pointers to first sets for each nonterminal */ extern int *pempty ; /* table of nonterminals nontrivially deriving e */ extern int nnonter ; /* the number of nonterminals */ extern int lastred ; /* the number of the last reduction of a state */ extern int ftable; /* y.tab.c file */ extern int foutput; /* y.output file */ extern int cin; /* current input file */ extern int cout; /* current output file */ extern int arrndx; extern int zzcwset; extern int zzpairs ; extern int zzgoent ; extern int zzgobest ; extern int zzacent ; extern int zzacsave ; extern int zznsave ; extern int zzclose ; extern int zzrrconf ; extern int zzsrconf ; extern char *ctokn; struct {int **ppi;} ; extern int ntlim ; /* maximum number of nonterminals */ extern int tlim ; /* maximum number of terminals */ extern int lineno; /* current line number */ extern int peekc; /* look-ahead character */ extern int tstates[]; extern int ntstates[]; extern int mstates[]; extern struct looksets clset; extern struct looksets lkst[]; extern int nlset; /* next lookahead set index */ extern int lsetsz; /* number of lookahead sets */ extern struct wset { int *pitem, flag, ws[ _tbitset ]; } wsets[]; extern int cwset; extern int wssize; extern int numbval; /* the value of an input number */ extern int rflag; /* ratfor flag */ extern int oflag; /* optimization flag */ extern int ndefout; /* number of defined symbols output */ extern int machine; # define UNIX 1 # define GCOS 2 # define IBM 3 ets clset; extern struct looksets lkst[]; extern int nlset; /* next lookahead set index */ extern int lsetsz; /* number of lookahead sets */ extern struct wset { int *pitem, flag, ws[ _tbitset ]; } wsets[main( argc, argv ) int argc; char *argv[]; { yyinit( argc, argv ); if( yyparse() ) return; yyaccpt(); } g; /* ratfor flag */ extern int oflag; /* optimization flag */ extern int ndefout; /* number of defined symbols output */ extern int machine; # define UNIX 1 # define GCOS 2 # define IBM 3 ets clset; extern struct looksets lkst[]; extern int nlset; /* next lookahead set index */ extern int lsetsz; /* number of lookahead sets */ extern struct wset { int *pitem, flag, ws[ _tbitset ]; } wsets[# # define YYFLAG1 -1000 # define YYFLAG2 -2000 /* test me on cases where there are more than one reduction per state, leading to the necessity to look ahead, and other arcane flows of control. */ # define YYMAXDEPTH 150 /* parser for yacc output */ extern int yyval; /* defined in the table file */ extern int yylval; /* defined in the table file */ extern int *yypv; /* defined in the table file */ int yydebug 0; /* 1 for debugging */ int yyv[YYMAXDEPTH]; /* where the values are stored */ int yychar -1; /* current input token number */ int yynerrs 0; /* number of errors */ int yyerrflag 0; /* error recovery flag */ yyparse() { extern int yypgo[], yyr1[], yyr2[], yyact[], yypact[]; extern int yydef[], yychk[]; extern int yylast, yyerrval; int yys[YYMAXDEPTH]; int yyj; register yyn, yystate, *yyps; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; yyps= &yys[0]-1; yypv= &yyv[0]-1; yystack: /* put a state and value onto the stack */ if( yydebug ) printf( "state %d, value %d, char %d\n",yystate,yyval,yychar ); *++yyps = yystate; *++yypv = yyval; yynewstate: yyn = yypact[yystate]; if( yyn<= YYFLAG1 ){ /* simple state */ if( yyn == YYFLAG2 && yychar<0 ) yychar = yylex(); goto yydefault; } if( yychar<0 ) yychar = yylex(); if( (yyn =+ yychar)<0 || yyn >= yylast ) goto yydefault; if( yychk[ yyn=yyact[ yyn ] ] == yychar ){ /* valid shift */ yychar = -1; yyval = yylval; yystate = yyn; if( yyerrflag > 0 ) --yyerrflag; goto yystack; } yydefault: /* default state action */ if( (yyn=yydef[yystate]) == -2 ) yyn = yyexcp( yystate ); if( yyn == -1 ){ /* accept */ return( 0 ); } if( yyn == 0 ){ /* error */ /* error ... attempt to resume parsing */ switch( yyerrflag ){ case 0: /* brand new error */ ++yynerrs; yyerror( "syntax error" ); case 1: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; /* find a state where "error" is a legal shift action */ while ( yyps >= yys ) { yyn = yypact[*yyps] + yyerrval; if( yyn>= 0 && yyn < yylast && yychk[yyact[yyn]] == yyerrval ){ yystate = yyact[yyn]; /* simulate a shift of "error" */ goto yystack; } yyn = yypact[*yyps]; /* the current yyps has no shift onn "error", pop stack */ if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *yyps, yyps[-1] ); --yyps; --yypv; } /* there is no state on the stack with an error shift ... abort */ abort: return(1); case 3: /* no shift yet; clobber input char */ if( yydebug ) printf( "error recovery discards char %d\n", yychar ); if( yychar == 0 ) goto abort; /* don't discard EOF, quit */ yychar = -1; goto yynewstate; /* try again in the same state */ }  } /* reduction by production yyn */ if( yydebug ) printf("reduce %d\n",yyn); yyps =- yyr2[yyn]; yypv =- yyr2[yyn]; yyval=yypv[1]; yyactr(yyn); /* consult goto table to find next state */ yyn = yyr1[yyn]; yyj = yypgo[yyn] + *yyps + 1; if( yyj>=yylast || yychk[ yystate = yyact[yyj] ] != -yyn ) yystate = yyact[yypgo[yyn]]; goto yystack; /* stack new state and value */ } o yynewstate; /* try again in the same state */ } # define _maxdepth 150 /* parser for yacc output */ extern int yyval; /* defined in the table file */ extern int yylval; /* defined in the table file */ extern int *yypv; /* defined in the table file */ int yydebug 0; /* 1 for debugging */ int yyv[_maxdepth]; /* where the values are stored */ int yystate 0; /* current parser state */ int yychar -1; /* current input token number */ int yynerrs 0; /* number of errors */ int yyerrflag 0; /* error recovery flag */ yyparse() { extern int yygo[], yypgo[], yyr1[], yyr2[], yyact[], yypact[]; auto int *ps, s[_maxdepth]; auto int ac, n, *p; yystate = 0; yychar = -1; yynerrs = 0; yyerrflag = 0; ps= &s[0]-1; yypv= &yyv[0]-1; stack: /* put a state and value onto the stack */ if( yydebug ) printf( "state %d, value %d, char %d\n",yystate,yyval,yychar ); *++ps = yystate; *++yypv = yyval; newstate: /* set ap to point to the parsing actions for the new state */ p = &yyact[ yypact[yystate+1] ]; actn: /* get the next action, and perform it */ n = ( ac = *p++ ) & 07777; /* n is the "address" of the action */ switch( ac>>12 ) { /* switch on operation */ case 1: /* skip on test */ if( yydebug && (yychar<0) ){ yychar = yylex(); printf( "character %d read\n", yychar ); } if( n != ( (yychar<0) ? ( yychar=yylex() ) : yychar ) ) ++p; goto actn; /* get next action */ case 2: /* shift */ yystate=n; yyval=yylval; yychar= -1; if( yyerrflag ) --yyerrflag; goto stack; /* stack new state */ case 3: /* reduce */ if( yydebug ) printf("reduce %d\n",n); ps =- yyr2[n]; yypv =- yyr2[n]; yyval=yypv[1]; yyactr(n); /* consult goto table to find next state */ for( p= &yygo[yypgo[yyr1[n]]]; *p != *ps && *p >= 0 ; p =+ 2 ) ; yystate = p[1]; goto stack; /* stack new state and value */ case 4: /* accept */ return(0); case 0: /* error ... attempt to resume parsing */  switch( yyerrflag ){ case 0: /* brand new error */ ++yynerrs; yyerror( "syntax error" ); case 1: case 2: /* incompletely recovered error ... try again */ yyerrflag = 3; /* find a state where "error" is a legal shift action */ while ( ps >= s ) { for( p= &yyact[ yypact[*ps+1] ] ; (*p>>12) == 1 ; p =+ 2 ) /* search ps actions */ if( *p == 4352 ) goto found; /* the current ps has no shift onn "error", pop stack */ if( yydebug ) printf( "error recovery pops state %d, uncovers %d\n", *ps, ps[-1] ); --ps; --yypv; } /* there is no state on the stack with an error shift ... abort */ abort: return(1); found: /* we have a state with a shift on "error", resume parsing */ yystate = p[1] & 07777; goto stack; case 3: /* no shift yet; clobber input char */ if( yydebug ) printf( "error recovery discards char %d\n", yychar ); if( yychar == 0 ) goto abort; /* don't discard EOF, quit */ yychar = -1; goto newstate; /* try again in the same state */ } } } k with an error shift ... abort */ abort: return(1); found: /* we have a state with a shift on "error", resume parsing */ yystate = p[1] & 07777; goto stack; case 3: /* no shift yet; clobber input char */ if( yydebug ) printf( "error recove# define _actsize 1500 # define _memsize 3500 # define _nstates 400 # define _nterms 95 # define _nprod 250 # define _nnonterm 100 # define _tempsize 400 # define _cnamsz 2000 # define _lsetsize 200 # define _wsetsize 150 # define _tbitset 6 int tbitset; /* size of lookahed sets */ int nolook 0; /* flag to suppress lookahead computations */ struct looksets { int lset[ _tbitset ]; } ; struct item { int *pitem; } ; /* this file contains the definitions for most externally known data */ int nstate 0; /* number of states */ struct item *pstate[_nstates]; /* pointers to the descriptions of the states */ int apstate[_nstates]; /* index to the actions for the states */ int tystate[_nstates]; /* contains type information about the states */ int stsize _nstates; /* maximum number of states, at present */ int memsiz _memsize; /* maximum size for productions and states */ int mem0[_memsize] ; /* production storage */ int *mem mem0; int amem[_actsize]; /* action table storage */ int actsiz _actsize; /* action table size */ int memact 0; /* next free action table position */ int nprod 1; /* number of productions */ int *prdptr[_nprod]; /* pointers to descriptions of productions */ int prdlim _nprod ; /* the maximum number of productions */ /* levprd - productions levels to break conflicts */ int levprd[_nprod] {0,0}; /* last two bits code associativity: 0 = no definition 1 = left associative 2 = binary 3 = right associative bit 04 is 1 if the production has an action the high 13 bits have the production level */ int nterms 0; /* number of terminals */ int tlim _nterms ; /* the maximum number of terminals */ /* the ascii representations of the terminals */ int extval 0; /* start of output values */ struct sxxx1 {char *name; int value;} trmset[_nterms]; char cnames[_cnamsz]; int cnamsz _cnamsz; char *cnamp; int maxtmp _tempsize; /* the size of the temp1 array */ int temp1[_tempsize]; /* temporary storage, indexed by terms + nterms or states */ int temp2[_nnonterm]; /* temporary storage indexed by nonterminals */ int trmlev[_nterms]; /* vector with the precedence of the terminals */ /* The levels are the same as for levprd, but bit 04 is always 0 */ /* the ascii representations of the nonterminals */ struct sxxx2 { char *name; } nontrst[_nnonterm]; int ntlim _nnonterm ; /* limit to the number of nonterminals */ int indgo[_nstates]; /* index to the stored goto table */ int ***pres; /* vector of pointers to the productions yielding each nonterminal */ struct looksets **pfirst; /* vector of pointers to first sets for each nonterminal */ int *pempty 0 ; /* table of nonterminals nontrivially deriving e */ int nnonter -1; /* the number of nonterminals */ int lastred 0; /* the number of the last reduction of a state */ int ftable; /* y.tab.c file */ int foutput; /* y.output file */ int arrndx; /* used in the output of arrays on y.tab.c */ int zzcwset 0; int zzpairs 0; int zzgoent 0; int zzgobest 0; int zzacent 0; int zzacsave 0; int zznsave 0; int zzclose 0; int zzsrconf 0; int zzrrconf 0; char *ctokn; int lineno 1; /* current input line number */ int peekc -1; /* look-ahead character */ int tstates[ _nterms ]; /* states generated by terminal gotos */ int ntstates[ _nnonterm ]; /* states generated by nonterminal gotos */ int mstates[ _nstates ]; /* chain of overflows of term/nonterm generation lists */ struct looksets clset; struct looksets lkst [ _lsetsize ]; int nlset 0; /* next lookahead set index */ int lsetsz _lsetsize; /* number of lookahead sets */ struct wset { int *pitem, flag, ws[_tbitset]; } wsets[ _wsetsize ]; int cwset; int wssize _wsetsize; int numbval; /* the value of an input number */ int rflag 0; /* ratfor flag */ int oflag 0; /* optimization flag */ int ndefout 3; /* number of defined symbols output */ int nerrors 0; /* number of errors */ int fatfl 1; /* if on, error is fatal */ int machine; /* has a number describing the machine */ nt nlset 0; /* next lookahead set index */ int lsetsz _lsetsize; /* number of lookahead sets */ struct wset { int *pite# include "dextern" /* * * * * y a c c * * * * */ /* features to be fixed up ... *** Print estimate of total space needed for parser *** Either list inputs on y.output, or list empty prdn's in states *** Mention nonterms not used (or, rules. not reduced) as nonfatal error *** Output states where conflicts were found by default on y.output *** Engage in newspeak: production=>grammar rules, term=>token, etc. *** handle # define, #ifdef, etc., in yacc actions, %{ %}  */ /* new features to be added *** reductions by single productions ( by request ) *** follow sets for start symbol *** option to only do slr(1) *** easily changed array names on output *** allocate core, rather than predefined *** input controlled by a grammar *** support multiple choices for conflicts *** better conflict diagnostics */ main(argc,argv) int argc; char *argv[]; { auto int n; whereami(); setup(argc,argv); /* initialize and read productions */ tbitset = (nterms+16)/16; cpres(); /* make table of which productions yield a given nonterminal */ cempty(); /* make a table of which nonterminals can match the empty string */ cpfir(); /* make a table of e free first lists */ stagen(); /* generate the states */ output(); /* write the states and the tables */ go2out(); summary(); windup(); } whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */ int i; i = 1; i = i << 30; if( i == 0 ) { machine = UNIX; return; } i = i << 4; if( i == 0 ){ machine = IBM; return; } machine = GCOS; } windup(){ /* no errors, do the optimization if appropriate */ char *cp; int i; cflush(1); if( !oflag ) cexit(0); for( i=3; i<10; ++i ) cclose(i); switch( machine ){ case GCOS: if( rflag ){ if( foutput<0 ) system( "./yopt -r" ); else system( "./yopt -rv" ); } else { if( foutput<0 ) system( "./yopt" ); else system( "./yopt -v" ); } cexit(0); /* terminate */ case UNIX: cp = "/usr/yacc/yopti"; if( rflag ) execl( cp, cp, (foutput<0)?"-r":"-rv", 0 ); else if( foutput<0 ) execl( cp, cp, 0 ); else execl( cp, cp, "-v", 0 ); error( "optimization execl call fails" ); case IBM: if( rflag ){ if( foutput<0 ) system( "MH2019.yaccopt -r" ); else system( "MH2019.yaccopt -rv" ); } else { if( foutput<0 ) system( "MH2019.yaccopt" ); else system( "MH2019.yaccopt -v" ); } cexit(0); } } settty() /* sets the output file to y.output */ { cflush( foutput ); /* a bit of a cheat */ cout = foutput; } settab(){ /* sets the output file to y.tab.c */ cflush( ftable ); cout = ftable; } char *chcopy( p, q ) char *p, *q; { /* copies string q into p, returning next free char ptr */ while( *p = *q++ ) ++p; return( p ); } char *writem(pp) struct item *pp; { /* creates output string for item pointed to by pp */ int i,*p; static char sarr[100]; char *q; char *symnam(); for( p=pp->pitem; *p>0 ; ++p ) ; p = prdptr[-*p]; q = chcopy( sarr, nontrst[*p-NTBASE].name ); q = chcopy( q, " : " ); for(;;){ *q++ = ++p==(pp->pitem) ? '_' : ' '; if((i = *p) <= 0) break; q = chcopy( q, symnam(i) ); } *q = '\0' ; return( sarr ); } char *symnam(i){ /* return a pointer to the name of symbol i */ char *cp; cp = (i>=NTBASE) ? nontrst[i-NTBASE].name : trmset[i].name ; if( *cp == ' ' ) ++cp; return( cp ); } summary(){ /* output the summary on the tty */ int i, s, *pn; if( !rflag ){ settab(); printf("\nint nterms %d;",nterms); printf("\nint nnonter %d;", nnonter); printf("\nint nstate %d;", nstate); printf("\nchar *yysterm[] {"); for (i=1;i<=nterms;i++) if( trmset[i].value >= 0400 ) printf("\n\"%s\",",symnam(i)); printf( "\n0 };\n" ); printf("\nchar *yysnter[] {"); for (i=0;i= memsiz) error("memory overflow"); return(omem); } aryfil( v, n, c ) int *v,n,c; { /* set elements 0 through n-1 to c */ int i; for( i=0; ilset; if( pp == 0 ) printf("\tNULL"); else { printf(" { " ); for( j=1; j<=nterms; ++j ){ if( (pp[j>>4]>>(j&017) )&01 != 0 ) printf( "%s ", symnam(j) ); } printf( "}" ); } } c; { /* set a to the union of b and c */# include "dextern" # define IDENTIFIER 257 # define MARK 258 # define TERM 259 # define LEFT 260 # define BINARY 261 # define RIGHT 262 # define PREC 263 # define LCURLY 264 # define C_IDENTIFIER 265 /* name followed by colon */ # define NUMBER 266 setup(argc,argv) int argc; char *argv[]; { int i,j,lev,t; int c; foutput = -2; i = 1; while( argc >= 2 && argv[1][0] == '-' ) { while( *++(argv[1]) ){ switch( *argv[1] ){ case 'v': case 'V': foutput = copen("y.output", 'w' ); if( foutput < 0 ) error( "cannot open y.output"); continue; case 'o': case 'O': oflag = 1; continue; case 'r': case 'R': oflag = 1; rflag = 1; continue; default: error( "illegal option: %c", *argv[1]); } } argv++; argc--; } ftable = copen( oflag ? "yacc.tmp" : "y.tab.c" , 'w' ); if( ftable<0 ) error( "cannot open table file" ); if( argc > 1 ) cin = copen( argv[1], 'r' ); if( cin < 0 ) error( "cannot open input" ); settab(); printf("#\n"); ctokn = "$end"; defin(0); /* eof */ extval = 0400; /* beginning of assigned values */ ctokn = "error"; defin(0); ctokn = "$accept"; defin(1); mem=mem0; cnamp = cnames; lev=0; i=0; while( t = gettok() ){ switch( t ){ case IDENTIFIER: j = chfind(0); trmlev[j] = lev; continue; case ',': case ';': continue; case TERM: lev=0; continue; case LEFT: lev=(++i<<3)|01; continue; case BINARY: lev=(++i<<3)|02; continue; case RIGHT: lev=(++i<<3)|03; continue; case MARK: defout();  if( rflag ){ /* RATFOR */ printf( "define yyerrok yyerrf = 0\n" ); printf( "define yyclearin yychar = -1\n" ); printf( "subroutine yyactr(yyprdn)\n"); printf( "common/yycomn/yylval,yyval,yypv,yyvalv(150)\n" ); printf( "common/yylcom/yychar,yyerrf,yydebu\n" ); printf( "integer yychar, yyerrf, yydebu\n" ); printf( "integer yyprdn,yyval,yylval,yypv,yyvalv\n" ); } else { printf( "#define yyclearin yychar = -1\n" ); printf( "#define yyerrok yyerrflag = 0\n" ); printf( "extern int yychar, yyerrflag;\n" ); printf("\nint yyval 0;\nint *yypv;\nint yylval 0;"); printf("\nyyactr(__np__){\n"); } break; case LCURLY: defout(); cpycode(); continue; case NUMBER: trmset[j].value = numbval; if( j < ndefout && j>2 ) error("please define type # of %s earlier", trmset[j].name ); continue; default: error("bad precedence syntax, input %d", t ); } break; } prdptr[0]=mem; /* added production */ *mem++ = NTBASE; *mem++ = NTBASE+1; *mem++ = 1; *mem++ = 0; prdptr[1]=mem; i=0; /* i is 0 when a rule can begin, 1 otherwise */ for(;;) switch( t=gettok() ) { case C_IDENTIFIER: if( mem == prdptr[1] ) { /* first time */ if( rflag ){ printf( "goto 1000\n" ); } else printf("\nswitch(__np__){\n"); } if( i != 0 ) error( "previous rule not terminated" ); *mem = chfind(1); if( *mem < NTBASE )error( "token illegal on lhs of grammar rule" ); i=1; ++mem; continue; case IDENTIFIER: *mem=chfind(1); if(*mem < NTBASE)levprd[nprod]=trmlev[*mem]; mem++; if(i==0) error("missing :"); continue; case '=': levprd[nprod] =| 04; if( i==0 ) error("semicolon preceeds action"); printf( rflag?"\n%d ":"\ncase %d:", nprod ); cpyact(); printf( rflag ? " return" : " break;" ); case '|': case ';': if(i){ *mem++ = -nprod; prdptr[++nprod] = mem; levprd[nprod]=0; i=0;} if (t=='|'){i=1;*mem++ = *prdptr[nprod-1];} continue; case 0: /* End Of File */ case MARK: if( i != 0 ) error( "rule not terminated before %%%% or EOF" ); settab(); finact(); /* copy the programs which follow the rules */ if( t == MARK ){ while (c=getchar()) putchar(c); } return; case PREC: if( i==0 ) error( "%%prec must appear inside rule" ); if( gettok()!=IDENTIFIER)error("illegal %%prec syntax" ); j=chfind(2); if(j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name); levprd[nprod]=trmlev[j]; continue; case LCURLY: if( i!=0 ) error( "%%{ appears within a rule" ); cpycode(); continue; default: error( "syntax error, input %d", t ); } } finact(){ /* finish action routine */ register i; if( rflag ){ printf( "\n1000 goto(" ); for( i=1; i= ntlim ) error("too many nonterminals, limit %d",ntlim); nontrst[nnonter].name = ctokn; return( NTBASE + nnonter ); } else { if( ++nterms >= tlim ) error("too many terminals, limit %d",tlim ); trmset[nterms].name = ctokn; if( ctokn[0]==' ' && ctokn[2]=='\0' ) /* single character literal */ trmset[nterms].value = ctokn[1]; else if ( ctokn[0]==' ' && ctokn[1]=='\\' ) { /* escape sequence */ if( ctokn[3] == '\0' ){ /* single character escape sequence */ switch ( ctokn[2] ){ /* character which is escaped */ case 'n': trmset[nterms].value = '\n'; break; case 'r': trmset[nterms].value = '\r'; break; case 'b': trmset[nterms].value = '\b'; break; case 't': trmset[nterms].value = '\t'; break; case '\'': trmset[nterms].value = '\''; break; case '"': trmset[nterms].value = '"'; break; case '\\': trmset[nterms].value = '\\'; break; default: error( "invalid escape" ); } } else if( ctokn[2] <= '7' && ctokn[2]>='0' ){ /* \nnn sequence */ if( ctokn[3]<'0' || ctokn[3] > '7' || ctokn[4]<'0' || ctokn[4]>'7' || ctokn[5] != '\0' ) error("illegal \\nnn construction" ); trmset[nterms].value = 64*(ctokn[2]-'0')+8*(ctokn[3]-'0')+ctokn[4]-'0'; if( trmset[nterms].value == 0 ) error( "'\\000' is illegal" ); } } else { trmset[nterms].value = extval++;  } trmlev[nterms] = 0; return( nterms ); } } defout(){ /* write out the defines (at the end of the declaration section) */ _REGISTER int i, c; _REGISTER char *cp; for( i=ndefout; i<=nterms; ++i ){ cp = trmset[i].name; if( *cp == ' ' ) ++cp; /* literals */ for( ; (c= *cp)!='\0'; ++cp ){ if( c>='a' && c<='z' || c>='A' && c<='Z' || c>='0' && c<='9' || c=='_' ) ; /* VOID */ else goto nodef; } /* define it */ printf( "%c define %s %d\n", rflag?' ':'#', trmset[i].name, trmset[i].value ); nodef: ; } ndefout = nterms+1; } chstash( c ){ /* put character away into cnames */ if( cnamp >= &cnames[cnamsz] ) error("too many characters in id's and literals" ); else *cnamp++ = c; } int gettok() { int j, base; static int peekline; /* number of '\n' seen in lookahead */ auto int c, match, reserve; begin: reserve = 0; if( peekc>=0 ) { c = peekc; lineno =+ peekline; peekc = -1; peekline = 0; } else c = getchar();  while( c==' ' || c=='\n' || c=='\t' ){ if( c == '\n' ) ++lineno; c=getchar(); } if (c=='/') {if (getchar()!='*')error("illegal /"); c=getchar(); while(c) { if( c == '\n' ) ++lineno; if (c=='*') {if((c=getchar())=='/')break;} else c=getchar();} if (!c) return(0); goto begin;} j=0; switch(c){ case '"': case '\'': match = c; ctokn = cnamp; chstash( ' ' ); while(1){ c = getchar(); if( c == '\n' || c == '\0' ) error("illegal or missing ' or \""); if( c == '\\' ){ c = getchar(); chstash( '\\' ); } else if( c == match ) break; chstash( c ); } break; case '%': case '\\': switch(c=getchar()) {case '0': return(TERM); case '<': return(LEFT); case '2': return(BINARY); case '>': return(RIGHT); case '%': case '\\': return(MARK); case '=': return(PREC); case '{': return(LCURLY); default: reserve = 1; } default: if( c >= '0' && c <= '9' ){ /* number */ numbval = c-'0' ; base = (c=='0') ? 8 : 10 ; for( c=getchar(); c>='0' && c<='9'; c=getchar() ){ numbval = numbval*base + c - '0'; } peekc = c; return(NUMBER); } else if( (c>='a'&&c<='z')||(c>='A'&&c<='Z')||c=='_'||c=='.'||c=='$'){ ctokn = cnamp; while( (c>='a'&&c<='z') || (c>='A'&&c<='Z') || (c>='0'&&c<='9') || c=='_' || c=='.' || c=='$' ) { chstash( c ); if( peekc>=0 ) { c = peekc; peekc = -1; } else c = getchar(); } } else return(c); peekc=c;  } chstash( '\0' ); if( reserve ){ /* find a reserved word */ if( compare("term")) return( TERM ); if( compare("TERM")) return( TERM ); if( compare("token")) return( TERM ); if( compare("TOKEN")) return( TERM ); if( compare("left")) return( LEFT ); if( compare("LEFT")) return( LEFT ); if( compare("nonassoc")) return( BINARY ); if( compare("NONASSOC")) return( BINARY ); if( compare("binary")) return( BINARY ); if( compare("BINARY")) return( BINARY ); if( compare("right")) return( RIGHT ); if( compare("RIGHT")) return( RIGHT ); if( compare("prec")) return( PREC ); if( compare("PREC")) return( PREC ); error("invalid escape, or illegal reserved word: %s", ctokn ); } /* look ahead to distinguish IDENTIFIER from C_IDENTIFIER */ look: while( peekc==' ' || peekc=='\t' || peekc == '\n' ) { if( peekc == '\n' ) ++peekline; peekc = getchar(); } if( peekc != ':' ) return( IDENTIFIER ); peekc = -1; lineno =+ peekline; peekline = 0; return( C_IDENTIFIER ); } chfind(t) { int i,j; if (ctokn[0]==' ')t=0; for(i=1;i<=nterms;i++) if(compare(trmset[i].name)){ cnamp = ctokn; return( i ); } for(i=1;i<=nnonter;i++) if(compare(nontrst[i].name)) { cnamp = ctokn; return( i+NTBASE ); } /* cannot find name */ if( t>1 && ctokn[0] != ' ' ) error( "%s should have been defined earlier", ctokn ); return( defin( t ) ); } cpycode(){ /* copies code between \{ and \} */ int c; c = getchar(); if( c == '\n' ) { c = getchar(); lineno++; } while( c ){ if( c=='\\' ) if( (c=getchar()) == '}' ) return; else putchar('\\'); if( c=='%' ) if( (c=getchar()) == '}' ) return; else putchar('%'); putchar( c ); if( c == '\n' ) ++lineno; c = getchar(); } error("eof before %%}"); } cpyact(){ /* copy C action to the next ; or closing } */ int brac, c, match, *i, j, s; brac = 0; loop: c = getchar(); swt: switch( c ){ case ';': if( brac == 0 ){ putchar( c ); return; } goto lcopy; case '{': brac++; goto lcopy; case '$': s = 1; c = getchar(); if( c == '$' ){ printf("yyval"); goto loop; } if( c == '-' ){ s = -s; c = getchar(); } if( c>='0' && c <= '9' ){ j=0; while( c>='0' && c<= '9' ){ j= j*10+c-'0'; c = getchar(); } if( rflag ) printf( "yyvalv(yypv%c%d)", s==1?'+':'-', j ); else printf("yypv[%d]", s*j ); goto swt; } putchar( '$' ); if( s<0 ) putchar('-'); goto swt; case '}': brac--; if( brac == 0 ){ putchar( c ); return; } goto lcopy; case '/': /* look for comments */ putchar( c ); c = getchar(); if( c != '*' ) goto swt; /* it really is a comment */ putchar( c ); while( c=getchar() ){ if( c=='*' ){ putchar( c ); if( (c=getchar()) == '/' ) goto lcopy; } putchar( c ); } error( "EOF inside comment" ); case '\'': /* character constant */ match = '\''; goto string; case '"': /* character string */ match = '"'; string: putchar( c ); while( c=getchar() ){ if( c=='\\' ){ putchar( c ); c=getchar(); } else if( c==match ) goto lcopy; putchar( c ); } error( "EOF in string or character constant" ); case '\0': error("action does not terminate"); case '\n': ++lineno; goto lcopy; } lcopy: putchar( c ); goto loop; } char( c ); } error( "EOF inside comment" ); case '\'': /* character constant */ match = '\''; goto string; case '"': /* character string */ match = '"'; string: putchar( c ); while( c=getchar() ){ if( c=='\\' ){ putchar( c ); c=getchar(# include "dextern" cpres(){ /* conpute an array with the beginnings of productions yielding given nonterminals The array pres points to these lists */ int i,j,c; pres = yalloc(nnonter+1); for(i=0;i<=nnonter;i++){ c = i+NTBASE; pres[i] = mem; fatfl = 0; /* make undefined symbols nonfatal */ for(j=0;j 0 ; ++p ) { if( ch < NTBASE ) { wsets[i].ws[ch>>4] =| (1 << (ch&017) ); break; }  else if( !pempty[ch-NTBASE] ) break; } } } /* now, reflect transitivity */ changes = 1; while( changes ){ changes = 0; for( i=0; i<=nnonter; ++i ){ t = pres[i+1]; for( s=pres[i]; s= 0; ++p ) { changes =| union( wsets[i].ws, wsets[i].ws, wsets[ch].ws ); if( !pempty[ch] ) break; } } } } for( i=0; i<=nnonter; i++ ) pfirst[i] = flset( wsets[i].ws ); if( !indebug ) return; settty(); for( i=0; i<=nnonter; i++ ){ printf( "\n%s: ", nontrst[i].name ); prlook( pfirst[i] ); printf( " %d\n", pempty[i] ); } } state(c){ /* sorts last state,and sees if it equals earlier ones. returns state number */ int s,size1,size2; _REGISTER i; struct item *p1, *p2, *k, *l, *q1, *q2; p1 = pstate[nstate]; p2 = pstate[nstate+1]; if(p1==p2) return(0); /* null state */ /* sort the items */ for(k=p2-1;k>p1;k--) { /* make k the biggest */ for(l=k-1;l>=p1;--l)if( l->pitem > k->pitem ){ s = k->pitem; k->pitem = l->pitem; l->pitem = s; s = k->look; k->look = l->look; l->look = s; } } size1 = p2 - p1; /* size of state */ for( i= (c>=NTBASE)?ntstates[c-NTBASE]:tstates[c]; i != 0; i = mstates[i] ) { /* get ith state */ q1 = pstate[i]; q2 = pstate[i+1]; size2 = q2 - q1; if (size1 != size2) continue; k=p1; for(l=q1;lpitem != k->pitem ) break; ++k; } if (l != q2) continue; /* found it */ pstate[nstate+1] = pstate[nstate]; /* delete last state */ /* fix up lookaheads */ k=p1; for( l=q1; llook->lset, k->look->lset ) ) { tystate[i] = 1; /* register the new set */ l->look = flset( &clset ); } ++k; } return (i); } /* state is new */ pstate[nstate+2] = p2; if(nstate+1 >= stsize) error("too many states"); if( c >= NTBASE ){ mstates[ nstate ] = ntstates[ c-NTBASE ]; ntstates[ c-NTBASE ] = nstate; } else { mstates[ nstate ] = tstates[ c ]; tstates[ c ] = nstate; } tystate[nstate]=1; return(nstate++); } int pidebug 0; /* debugging flag for putitem */ putitem ( ptr, lptr ) int *ptr; struct looksets *lptr;{ int *jip, k; struct item *i, *j; if( pidebug ) { settty(); printf("putitem(%s), state %d\n", writem(&ptr), nstate ); } /* see if it's there */ j = pstate[nstate+1]; for( i=pstate[nstate]; ipitem == ptr) { error("yacc error--duplicate item"); } /* not there */ j->pitem = ptr; j->look = flset( lptr ); pstate[nstate+1] = ++j; jip = j; if(jip-mem0 >= memsiz) error("out of state space"); } cempty(){ /* mark nonterminals which derive the empty string */ int i, *p; /* set pempty to 0 */ pempty = yalloc( nnonter ); aryfil( pempty, nnonter+1, 0 ); for( i=1; i=NTBASE && pempty[*p-NTBASE]!=0 ; ++p ) ; if( *p < 0 ){ /* we have a nontrivially empty nonterminal */ pempty[*prdptr[i]-NTBASE] = 1; goto again; /* got one ... try for another */ } } } } int gsdebug 0; stagen(){ /* generate the states */ int i, j, k, c; /* initialize */ nstate = 0; pstate[0] = pstate[1] = mem; aryfil( clset.lset, tbitset, 0 ); putitem( prdptr[0]+1, &clset ); tystate[0] = 1; nstate = 1; pstate[2] = pstate[1]; memact = 0; aryfil( amem, actsiz, 0 ); /* now, the main state generation loop */ more: for( i=0; ipitem; wsets[cwset].flag = 1; /* this item must get closed */ for( k=0; klook->lset[k]; ++cwset; } /* now, go through the loop, closing each item */ work = 1; while( work ){ work = 0; for( j=0; j0 ){ if( ch < NTBASE ){ /* terminal symbol */ clset.lset[ch>>4] =| (1<<(ch&017)); break; } /* nonterminal symbol */ union( clset.lset, clset.lset, pfirst[ch-NTBASE] ); if( !pempty[ch-NTBASE] ) break; } if( ch<=0 ) union( clset.lset, clset.lset, wsets[k].ws ); } } /* now loop over productions derived from c */ c =- NTBASE; /* c is now nonterminal number */ t = pres[c+1]; for( s=pres[c]; s= wssize ) error( "working set overflow" ); wsets[cwset].pitem = *s; wsets[cwset].flag = 1; if( nolook ){ cwset++; goto nexts; } work = 1; for( k=0; k zzcwset ) zzcwset = cwset; if( !cldebug ) return; settty(); printf("\nState %d, nolook = %d\n", i, nolook ); for( j=0; jlset; v = lkst[i].lset; w = & v[tbitset]; while( v= lsetsz )error("too many lookahead sets"); for( j=0; jlset[j]; } return( & lkst[nlset++]); } ide if the lookahead set pointed to by p is kn# include "dextern" output(){ /* print the output for the states */ int i, j, k, c; settab(); arrset("yyact"); for( i=0; i0 && c>4])&(1<<(k&017))) != 0 ) { if( temp1[k] == 0 ) temp1[k] = c; else if( temp1[k]<0 ){ /* reduce/reduce conflict */ settty(); printf("\n%d: reduce/reduce conflict (red'ns %d and %d ) on %s", i, -temp1[k], lastred, symnam(k) ); if( -temp1[k] > lastred ) temp1[k] = -lastred; ++zzrrconf; settab(); } else { /* potential shift/reduce conflict */ switch( precftn( lastred, k ) ) { case 0: /* precedence does not apply */ settty(); printf("\n%d: shift/reduce conflict (shift %d, red'n %d) on %s", i, temp1[k], lastred, symnam(k) ); ++zzsrconf; settab();  break; case 1: /* reduce */ temp1[k] = -lastred; break; case 2: /* error, binary operator */ temp1[k] = ERRCODE; break; case 3: /* shift ... leave the entry alone */ break; } } } } } } wract(i); } settab(); arrdone(); /* now, output the pointers to the action array */ /* also output the info about reductions */ prred(); } prred(){ /* print the information about the actions and the reductions */ int index, i; arrset("yypact"); index = 1; /* position in the output table */ for( i=0; i0 ){ /* the state is real */ temp1[i] = index; arrval( index ); index =+ tystate[i]; } else { arrval( temp1[-tystate[i]] ); } } arrdone(); arrset("yyr1"); for( i=1; i j ){ /* no actions */ return(0); } j =- off; for( k=0; k= actsiz ) error("action table overflow"); if( k+l >= memact ) memact = k+l; amem[k+l] = p[off+l];  } } if( pkdebug ){ for( k=0; k times ){ best = cbest; times = count; } } /* best is now the default entry */ zzgobest =+ (times-1)*2;  settab(); for( j=0; j<=nstate; ++j ){ if( tystate[j] != 0 && tystate[j]!=best ){ arrval( j ); arrval( tystate[j] ); offset =+ 2; zzgoent =+ 2; } } /* now, the default */ zzgoent =+ 2; arrval( -1 ); arrval( best ); offset =+ 2; } arrdone(); arrset("yypgo"); for( i=1; i<=nnonter; ++i ) arrval( temp2[i] ); arrdone(); } int g2debug 0; go2gen(c){ /* output the gotos for nonterminal c */ int i, work, cc; struct item *p, *q; /* first, find nonterminals with gotos on c */ aryfil( temp1, nnonter+1, 0 ); temp1[c] = 1; work = 1; while( work ){ work = 0; for( i=0; i= 0 ){ /* cc is a nonterminal */ if( temp1[cc] != 0 ){ /* cc has a goto on c */ cc = *prdptr[i]-NTBASE; /* thus, the left side of production i does too */ if( temp1[cc] == 0 ){ work = 1; temp1[cc] = 1; } }  } } } /* now, we have temp1[c] = 1 if a goto on c in closure of cc */ if( g2debug ){ settty(); printf("%s: gotos on ", nontrst[c].name ); for( i=0; i<=nnonter; ++i ) if( temp1[i]) printf("%s ", nontrst[i].name); printf("\n"); } /* now, go through and put gotos into tystate */ aryfil( tystate, nstate, 0 ); settty(); printf("\nnonterminal %s\n", nontrst[c].name ); for( i=0; ipitem) >= NTBASE ){ if( temp1[cc =- NTBASE] ){ /* goto on c is possible */ tystate[i] = amem[indgo[i]+c]; break; } } } if( tystate[i] ) printf("\t%d\t%d\n", i, tystate[i]); } } precftn(r,t){ /* decide a shift/reduce conflict by precedence. Returns 0 if action is 'do nothing',1 if action is reduce, 2 if the action is 'error,binary operator' and 3 if the action is 'reduce'. */ int lp,lt; lp = levprd[r]; lt = trmlev[t]; if ((lt==0)||((lp&03)==0))return(0); if((lt>>3) == (lp>>3)){ return(lt&03); } if((lt>>3) > (lp>>3)) return(3); return(1); } int cdebug 0; /* debug for common states */ wract(i){ /* output state i */ /* temp1 has the actions, lastred the default */ int p, p0, p1, size; int ntimes, tred, count, j; struct item *q0, *q1; /* find the best choice for lastred */ lastred = 0; ntimes = 0; for( j=1; j<=nterms; ++j ){ if( temp1[j] >= 0 ) continue; if( temp1[j]+lastred == 0 ) continue; /* count the number of appearances of temp1[j] */ count = 0; tred = -temp1[j]; for( p=1; p<=nterms; ++p ){ if( temp1[p]+tred == 0 ) ++count; } if( count >ntimes ){ lastred = tred; ntimes = count; } } /* clear out entries in temp1 which equal lastred */ for( p=1; p<= nterms; ++p ) if( temp1[p]+lastred == 0 )temp1[p]=0; /* write out the state */ /* first, check for equality with another state */ /* see if there is a nonterminal with all dots before it. */ p0 = 0; q1 = pstate[i+1]; for( q0=pstate[i]; q0pitem) ) < NTBASE ) goto standard; if( p0 == 0 ) p0 = p1; else if( p0 != p1 ) goto standard; } /* now, all items have dots before p0 */ if( cdebug ){ settty(); printf("state %d, pre-nonterminal %s\n",i,nontrst[p0-NTBASE].name); } for( j=0; jpitem) != p0 ) goto nextj; } /* we have a match with state j ! */ tystate[i] = -j; zzacsave =+ tystate[j]; zznsave++; wrstate(i); return; nextj: ; } standard: tystate[i] = 2; wrstate(i); size = 0; for( p0=1; p0<=nterms; ++p0 ) if( (p1=temp1[p0])!=0 ) { arrval( TESTACT+trmset[p0].value ); if( p1 < 0 ) arrval( REDUCACT - p1 ); else if( p1 == ACCEPTCODE ) arrval( ACCEPTACT ); else if( p1 == ERRCODE ) arrval( ERRACT ); else arrval( SHIFTACT + p1 ); size =+ 2; } if( lastred ) arrval( REDUCACT + lastred ); else arrval( ERRACT ); tystate[i] = size+1; /* store entry size in tystate */ zzacent =+ (size+1); return; } wrstate(i){ /* writes state i */ int j0,j1,s; struct item *pp, *qq; settty(); printf("\nstate %d\n",i); qq = pstate[i+1]; for( pp=pstate[i]; pp0 ){ /* shift, error, or accept */ if( j1 == ACCEPTCODE ) printf( "accept" ); else if( j1 == ERRCODE ) printf( "error" ); else printf( "shift %d", j1 ); } else printf("reduce %d",-j1 ); } /* output the final production */ if( lastred ) printf("\n\t. reduce %d\n\n", lastred ); else printf("\n\t. error\n\n" ); ret: settab(); } j0=1; j0<=nterms; ++j0 ) if( (j1=temp1[j0]) != 0 ){ printf("\n\t%s ", symnam(j0) ); if( j1>0 ){ /* shift, error, or accept */ if( j1 == ACCEPTCODE ) printf( "accept" ); else if( j1 == ERRCODE ) print/* fake portable I/O routines, for those sites so backward as to not have the port. library */ int cin, cout; extern int fin, fout; copen( s, c ) char *s; { int f; if( c == 'r' ){ fin = f = open( s, 0 ); } else if( c == 'a' ){ f = open( s, 1 ); seek( f, 0, 2 ); } else { /* c == w */ f = creat( s, 0666 ); } return( f ); } cflush(x){ /* fake! sets file to x */ flush(); fout = x; } system(){ error( "The function \"system\" is called" ); } cclose(i){ close(i); } cexit(i){ flush(); exit(i); } d as to not have the port. library */ int cin, cout; extern int fin, fout; copen( s, c ) char *s; { int f; if( c == 'r' ){ fin = f = open( s, 0 ); } else if( c == 'a' ){ f = open( s, 1 ); seek( f, 0, 2 ); } else { /* c == w */ f = creat( s, 0666 ); } return( f ); } cflush(x){ /* fake! sets file to x */ flush(); fout = x; } system(){ error( "The function \"system\" is called" ); } ccl# define NOMORE -1000 # define FLAG1 -1000 # define FLAG2 -2000 # define msize 4000 # define asize 4000 /* machine types */ # define GCOS 1 # define UNIX 2 # define IBM 3 /* wishlist */ /* make the def, and a arrays byte arrays whenever possible /* also, yyr1, yyr2, etc.. /* check for error recovery botch in parser.c /* use defines for limits, like yacc */ extern int cin; extern int cout; int machine; /* has machine type */ int *yyact; int *yypact; int *yyr1; int *yyr2; int *yygo; int *yypgo; int mem[ msize ]; int *pmem { mem }; int nterms; int nnonter; int nstate; int nprod; int *endact; int a[asize]; /* representation of the parser */ int *maxa; int pa[350]; /* index into a */ int def[350]; /* defaults*/ int chk[350]; /* checks */ int sym[400] ; /* terminal symbols */ int temp[400]; int greed[350]; int pgo[350]; int ggreed[100]; int *psym ; /* pointer to next symbol slot */ int rsym; /* range of symbols */ int maxoff; /* maximum offset into a array */ int nxdb 0; int dfdb 0; int chkdb 0; int symdb 0; int adb 0; int nentr 0; int alpha 1; int beta 1; int grflg 1; int origfl 1; int rflag 0; int vflag 0; main( argc, argv ) char *argv[]; { register i, *p, j; int flag; /* get the options, if any */ if( argc > 1 ){ for( i=0; j=argv[1][i]; ++i ){ switch(j){ case 'g': grflg = 0; continue; case 'o': origfl = 0; continue; case 'r': rflag = 1; continue; case 'v': vflag = 1; continue; } } } /* open the input and output files */ cin = copen( "yacc.tmp", 'r' ); if( cin < 0 ) error( "missing yacc.tmp file" ); cout = copen( rflag ? "y.tab.r" : "y.tab.c", 'w' ); cflush( cout ); if( cout < 0 ) error( "missing output file" ); whereami(); /* determine environment */ /* read the arrays from yacc.tmp and set parameters */ i = arget( "int yyact", &yyact ); nstate = arget( "int yypact", &yypact ) - 2; nprod = arget( "int yyr1", &yyr1 ) - 1; arget( "int yyr2", &yyr2 ); arget( "int yygo", &yygo ); nnonter = arget( "int yypgo", &yypgo ) - 2; if( nnonter < 1 ) error( "bad format on yacc.tmp" ); arget( "yyact", &endact ); /* garbage to copy rest of file */ /* get the default actions; always reduce or error */ for( i=0; i<350; ++i ) chk[i] = 0; for( i=0; i>12 == 1; p =+ 2 ){ if( (*p&07777) > j ) j = *p&07777; if( p[1]>>12 == 2 ) ++greed[i]; /* count shifts */ } nentr =+ greed[i]; greed[i] = alpha*greed[i] + beta*j; def[i] = *p&07777; if( dfdb ) printf( "State %d, default %d\n", i, def[i] ); } /* initialize ggreed table */ for( i=1; yypgo[i]>0; ++i ){ ggreed[i] = 1; j = 0; for( p= &yygo[yypgo[i]]; *p>0; p =+ 2 ) { ++ggreed[i]; if( *p > j ) j = *p; chk[ p[1] ] = -i; } chk[ p[1] ] = -i; ggreed[i] = alpha*ggreed[i] + beta*j; } /* initialize sym table */ for( i=0; i<400; ++i ) sym[i] = 0; psym = sym+1; /* find end of yyact */ endact = yypact - 1; /* make table of tests and symbols */ for( p=yyact; p>12 == 1 ){ /* a test */ j = lsym( *p ); if( p[1]>>12 == 2 ) { /* a shift */ i = p[1]&07777; /* the target state */ if( chk[i] != 0 && chk[i] != j ){ /* error */ error("Position %d, state %d, %d onto %d\n", p-yyact, i, j, chk[i] ); } chk[i] = j; } } } if( chkdb ){ for( i=0; i= maxoff ) maxoff = nstate+1; /* now, prepare to put the shift actions into the a array */ for( i=0; i1 ) printf( "State %d: null\n", i ); pa[i] = FLAG1; } while( (i = nxti()) != NOMORE ) { if( i >= 0 ) stin(i); else gin(-i); } if( adb>2 ){ /* print a array */ for( p=a; p <= maxa; p =+ 10){ printf( "%4d ", p-a ); for( i=0; i<10; ++i ) printf( "%4d ", p[i] ); printf( "\n" ); } } /* write out the output appropriate to the language */ if( rflag ) routput(); else output(); summary(); zaptemp(); cexit(0); } gin(i){ register *p, j, flag; /* enter gotos on nonterminal i into array a */ ggreed[i] = 0; /* first, fill temp array; 0 has default */ for( j=0; j<400; ++j ) temp[j] = 0; for( p = &yygo[yypgo[i]]; *p >= 0; p =+ 2 ){ temp[ *p+1 ] = p[1]; } temp[0] = p[1]; /* now, find a place for it */ for( p=a; p < &a[asize]; ++p ){ for( j=0; j &a[asize] ) error( "a array overflow" ); p[j] = temp[j]; } } pgo[i] = p-a; if( adb>1 ) printf( "Nonterminal %d, entry at %d\n" , i, pgo[i] ); goto nextgi; nextgp: ; } error( "cannot place goto %d\n", i ); nextgi: ; } stin(i){ register flag, j, *p; greed[i] = 0; /* enter state i into the a array */ for( p = &temp[maxoff]; p>=temp; --p ) *p=0; for( p= &yyact[yypact[i+1]]; *p>>12==1; p =+ 2 ){ if( p[1]>>12 == 2 ){ /* shift */ temp[ lsym(*p) ] = p[1]&07777; } } /* temp array is now filled */ /* find an acceptable place for temp */ for( p=a-maxoff; p< &a[asize]; ++p ){ if( (flag = compat( p, temp) ) > 0 ) continue; if( flag ){ for( j=0; j1 ) printf( "State %d: entry at %d\n", i, pa[i] ); goto nexti; nextp: ; } error( "Error; failure to place state %d\n", i ); nexti: ; } lsym( v ){ /* check that v is a known symbol */ register i, *p; i = v&07777; if( i > rsym ) rsym = i; for( p= sym; p maxa ) maxa = &p[i]; if( maxa > &a[asize] ) error( "a array overflow" ); if( p[i] != 0 && p[i] != q[i] ) error( "clobber of p array" ); p[i] = q[i]; } } error( s, x, y ) char *s; { cflush( 2 ); cout = 2; printf( "Fatal error:" ); printf( s, x, y ); printf( "\n" ); cexit(1); } nxti(){ /* finds the next i */ register i, max, maxi; if( grflg ){ /* be greedy; find the biggest */ max = 0; for( i=1; i<= nnonter; ++i ) if( ggreed[i] >= max ){ max = ggreed[i]; maxi = -i; } for( i=0; i= max ){ max = greed[i]; maxi = i; } if( nxdb ) printf( "nxti = %d, max = %d\n", maxi, max ); if( max==0 ) return( NOMORE ); else return( maxi ); } /* not greedy; take the first nonzero one */ for( i=1; i<= nnonter; ++i ) if( ggreed[i] > 0 ) return( -i ); for( i=0; i 0 ) return(i); return( NOMORE ); } summary(){ /* write summary */ register i, *p, j; if( !vflag ) return; i = copen( "y.output", 'a' ); if( i < 0 ) error( "cannot open y.output" ); cflush(i); cout = i; i=0; for( p=maxa; p>=a; --p ) { if( *p == 0 ) ++i; } printf( "\nOptimizer summary:\n" ); printf( "%d table entries, %d zero\n", (maxa-a)+1, i ); printf( "maximum offset: %d\n", maxoff ); /* space summary */ i = pmem-yyact+3; j = (maxa-a)+3*nstate+2*(nprod+1)+nnonter+5; printf( "Total space estimate(wds.): Old %d, new %d\n", i, j ); } output(){ /* this version is for C */ register i, *p, n; int flag; /* write out the optimized parser */ printf( "#\nextern int yychar;\n\n" ); printf( "int yylast %d;\n", maxa-a+1 ); /* write the translate function */ if( !origfl ){ printf( "yylex(){\n\tswitch( yyolex() ){\n" ); for( p = sym; p>12 == 1; p =+ 2 ){ if( p[1]>>12 != 2 ){ if( flag++ == 0 ) printf( "\tcase %d:\n", i); switch( p[1]>>12 ){ case 0: n = 0; break; case 4: n = -1; break; case 3: n = p[1]&07777; break; default: error( "disaster, state %d\n", i ); } printf( "\t\tif( yychar == %d ) return( %d );\n", lsym(*p), n ); } } if( flag ){ printf( "\t\treturn( %d );\n", def[i] ); def[i] = -2; if( pa[i]== -1000 )pa[i] = -2000; /* need yychar defined for this state */ } } printf( "\t\t}\n\t}\n\n" ); arout( "yyact", a, (maxa-a)+1 ); arout( "yypact", pa, nstate ); arout( "yypgo", pgo, nnonter+1 ); arout( "yyr1", yyr1, nprod+1 ); arout( "yyr2", yyr2, nprod+1 ); arout( "yychk", chk, nstate ); arout( "yydef", def, nstate ); /* append the optimised parser */ switch( machine ){ case UNIX: cin = copen( "/usr/yacc/opar.c", 'r' ); break; case GCOS: cin = copen( "./yaccopar", 'r' ); break; case IBM: cin = copen( "MH2019.yaccopar", 'r' ); break; } if( cin < 0 ) error( "cannot open optimized parser file" ); while( i = getchar() ) putchar(i); } arout( s, v, n ) char *s; int *v, n; { register i, j; printf( "%s[]{\n", s ); for( i=0; i= '0' ){ val = val * 10 + c - '0'; } else if ( c == '-' ) s = -1; else break; } *pmem++ = s*val; if( pmem > &mem[msize] ) error( "out of space" ); return( c ); } routput(){ /* produce ratfor output (groan! ); */ register i, n, *p; int flag; /* produce exception function */ printf( "integer function yyexcp( s, c )\n" ); printf( "integer s, c\n" ); for( i = 0; i>12 == 1; p =+ 2 ){ if( p[1] >>12 != 2 ){ if( flag++ == 0 ) printf( "if( s == %d ){\n" , i ); switch( p[1] >> 12 ){ case 0: n = 0; break; case 4: n = -1; break; case 3: n = p[1]&07777; break; default: error( "disaster, state %d", i ); } if( flag > 1 ) printf( "else" ); printf( "if( c== %d ) yyexcp= %d\n", lsym(*p), n ); } } if( flag ){ printf( "else yyexcp = %d\nreturn\n}\n", def[i] ); def[i] = -2; if( pa[i] == -1000 ) pa[i] = -2000; } } printf( "return\nend\n" ); printf( "integer function yypars( yyargu )\n" ); printf( "define YYLAST %d\n", (maxa-a)+1 ); printf( "common /yycomn/ yylval, yyval, yypv, yyvalv(150)\n" ); printf( "common /yylcom/ yychar, yyerrf, yydebu\n" ); printf( "integer yyval, yypv, yylval, yychar, yydebu, yynerr, yystat, yyargu\n" ); printf( "integer yylex, yyexcp, yys(150), yyerrf, yyvalv, yyn, yyj\n" ); pcom( "yyact", (maxa-a)+1 ); pcom( "yypact", nstate ); pcom( "yypgo", nnonter+1 ); pcom( "yyr1", nprod+1 ); pcom( "yyr2", nprod+1 ); pcom( "yychk", nstate ); pcom( "yydef", nstate ); farout( "yyact", a, (maxa-a)+1 ); farout( "yypact", pa, nstate ); farout( "yypgo", pgo, nnonter+1 ); farout( "yyr1", yyr1, nprod+1 ); farout( "yyr2", yyr2, nprod+1 ); farout( "yychk", chk, nstate ); farout( "yydef", def, nstate ); /* copy body of parser */ switch( machine ){ case UNIX: cin = copen( "/usr/yacc/rpar.r", 'r' ); break; case GCOS: cin = copen( "./yaccrpar", 'r' ); break; case IBM: cin = copen( "MH2019.yaccrpar", 'r' ); break; } if( cin < 0 ){ error( "cannot open ratfor parser file" ); cexit(1); } while( i=getchar() ) putchar(i); }  pcom( s, n ) char *s; { printf( " integer %s(%d)\n", s, n ); } farout( s, v, n ) char *s; int *v, n; { /* output the array v, size n, as array s, in fortran */ register i; for( i=1; i<=n; ++i ){ printf( " data %s(%d)/%d/;\n" , s, i, v[i-1] ); } } zaptemp(){ /* machine dependent; cream yacc.tmp */ switch( machine ){ case UNIX: unlink( "yacc.tmp" ); return; case GCOS: system( "remo yacc.tmp" ); return; case IBM: /* we just leave the temp file alone, to avoid screwups */ return; } } whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */ int i; i = 1; i = i << 30; if( i == 0 ) { machine = UNIX; return; } i = i << 4; if( i == 0 ){ machine = IBM; return; } machine = GCOS; } } zaptemp(){ /* machine dependent; cream yacc.tmp */ switch( machine ){ case UNIX: unlink( "yacc.tmp" ); return; case GCOS: system( "remo yacc.tmp" ); return; case IBM: /* we just leave the temp file alone, to avoid scyyaccpt(){} return; } } whereami(){ /* sets the variable machine to UNIX, GCOS, or IBM */ int i; i = 1; i = i << 30; if( i == 0 ) { machine = UNIX; return; } i = i << 4; if( i == 0 ){ machine = IBM; return; } machine = GCOS; } } zaptemp(){ /* machine dependent; cream yacc.tmp */ switch( machine ){ case UNIX: unlink( "yacc.tmp" ); return; case GCOS: system( "remo yacc.tmp" ); return; case IBM: /* we just leave the temp file alone, to avoid scextern int yyline; /* input line number */ yyerror(s) char *s; { extern int yychar; extern char *yysterm[]; printf("\n%s", s ); if( yyline ) printf(", line %d,", yyline ); printf(" on input: "); if( yychar >= 0400 ) printf("%s\n", yysterm[yychar-0400] ); else switch ( yychar ) { case '\t': printf( "\\t\n" ); return; case '\n': printf( "\\n\n" ); return; case '\0': printf( "$end\n" ); return; default: printf( "%c\n" , yychar ); return; } } he temp file alone, to avoid scyyinit(){} yyline; /* input line number */ yyerror(s) char *s; { extern int yychar; extern char *yysterm[]; printf("\n%s", s ); if( yyline ) printf(", line %d,", yyline ); printf(" on input: "); if( yychar >= 0400 ) printf("%s\n", yysterm[yychar-0400] ); else switch ( yychar ) { case '\t': printf( "\\t\n" ); return; case '\n': printf( "\\n\n" ); return; case '\0': printf( "$end\n" ); return; default: printf( "%c\n" , yychar ); return; } } he temp file alone, to avoid sc! "W N F=    @ #D  D ҃TT ^ B ы e@W 0 ,"& 7    " 7 -  X e5PߋRTV`RߋR RT `Re `R7 t*p ȋ@E A Ze   ?    7? eEopsys/conf.c\ *I?opsys/low.s( *IDggopsys/m40.s( SHlf# #include "../head/param.h" /* * Copyright 1974 Bell Telephone Laboratories Inc */ /* * Frozen Configuration Table - New devices may be * added to the end of the tables only! * block order - rk,rp,rf,tm,tc,hp,ht,hs,0 * character order - kl,pc,lp,dc,dh,dp,dj,dn,mem,rk,rf,rp,tm, * hp,ht,hs,sys,0 */ int (*bdevsw[])() { /* 0*/ &nodev, &nodev, &nodev, 0, /* 1*/ &rpopen, &nulldev, &rpstrategy, &rptab, /* 2*/ &nodev, &nodev, &nodev, 0, /* 3*/ &tmopen, &tmclose, &tmstrategy, &tmtab, /* 4*/ &nodev, &nodev, &nodev, 0, /* 5*/ &nodev, &nodev, &nodev, 0, /* 6*/ &nodev, &nodev, &nodev, 0, /* 7*/ &nodev, &nodev, &nodev, 0, 0 }; int (*cdevsw[])() { /* 0*/ &klopen, &klclose, &klread, &klwrite, &klsgtty, /* 1*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 2*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 3*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 4*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 5*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 6*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 7*/ &nodev, &nodev, &nodev, &nodev, &nodev, /* 8*/ &nulldev, &nulldev, &mmread, &mmwrite, &nodev, /* 9*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*10*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*11*/ &rpopen, &nulldev, &rpread, &rpwrite, &nodev, /*12*/ &tmopen, &tmclose, &tmread, &tmwrite, &nodev, /*13*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*14*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*15*/ &nodev, &nodev, &nodev, &nodev, &nodev, /*16*/ &nodev, &nodev, &nodev, &nodev, &nodev, 0 }; int (*ctlsw[])() { /* 0*/ &nulldev, &klmctl, /* 1*/ &nodev, &nodev, /* 2*/ &nodev, &nodev, /* 3*/ &nodev, &nodev, 0 }; int (*linesw[])() { &ttopen, &ttclose, &ttread, &ttwrite, &ttyinput,&ttxmtd, &ttmt, &ttstty, 0 }; int rootdev {(1<<8)|0}; int swapdev {(1<<8)|0}; int swplo 9200; int nswap 2000; int sysparam[]{ NPROC, NTEXT, NINODE, NFILE, NBUF, NMOUNT, NCLIST, 0 }; , &nodev, &nodev, /*16*/ &nodev, &nodev, &nodev, &nodev, &nodev, 0 }; int (*ctlsw[])() { /* 0*/ &nulldev, &klmctl, /* 1*/ &nodev, &nodev, /* 2*/ &nodev, &nodev, /* 3*/ &nodev, &nodev, 0 }; int (*linesw[])() { &ttopen, &ttclose, &ttread, &ttwrite, &ttyinput,&ttxmtd, &ttmt, &ttstty, 0 }; int rootdev {(1<<8)|0}; int swapdev {(1<<8)|0}; int swplo 9200; int ns/copyright 1974 Bell Telephone Laboratories Inc. /low core br4 = 200 br5 = 240 br6 = 300 br7 = 340 . = 0^. br 1f 4 / trap vectors trap; br7+0. / bus error trap; br7+1. / illeagle instruction trap; br7+2. / bpt-trace trap trap; br7+3. / iot trap trap; br7+4. / power fail trap; br7+5. / emulator trap trap; br7+6. / system entry . = 40^. .globl start, dump 1: jmp start jmp dump . = 50^. stray; br7+10. stray; br7+11. . = 60^. klin; br5 klou; br5 . = 70^. stray; br7+14. stray; br7+15. . = 100^. kwlp; br6 . = 104^. kwlp; br6 . = 110^. stray; br7+2. stray; br7+3. stray; br7+4. stray; br7+5. stray; br7+6. stray; br7+7. stray; br7+8. stray; br7+9. stray; br7+10. stray; br7+11. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. stray; br7+0. stray; br7+1. stray; br7+2. stray; br7+3. stray; br7+4. . = 224^. tmio; br5 . = 230^. stray; br7+6. stray; br7+7. . = 240^. trap; br7+7. / programmed interrupt trap; br7+8. / floating point trap; br7+9. / segmentation violation . = 254^. rpio; br5 . = 260^. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. / floating vectors stray; br7+0. stray; br7+1. stray; br7+2. stray; br7+3. stray; br7+4. stray; br7+5. stray; br7+6. stray; br7+7. stray; br7+8. stray; br7+9. stray; br7+10. stray; br7+11. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. stray; br7+0. ////////////////////////////////////////////////////// / interface code to C ////////////////////////////////////////////////////// .globl call, trap .globl _klrint klin: jsr r0,call; _klrint .globl _klxint klou: jsr r0,call; _klxint .globl _clock kwlp: jsr r0,call; _clock .globl _tmintr tmio: jsr r0,call; _tmintr .globl _rpintr rpio: jsr r0,call; _rpintr .globl _stray stray: jsr r0,call; _stray br7+10. stray; br7+11. stray; br7+12. stray; br7+13. stray; br7+14. stray; br7+15. stray; br7+0. ////////////////////////////////////////////////////// / interface code to C ////////////////////////////////// machine language assist / for 11/40 .mt = 1 /1 = tm11 0 = tju16 / non-UNIX instructions mfpi = 6500^tst mtpi = 6600^tst wait = 1 rtt = 6 reset = 5 .globl trap, call .globl _trap trap: mov PS,-4(sp) tst nofault bne 1f mov SSR0,ssr mov SSR2,ssr+4 mov $1,SSR0 jsr r0,call1; _trap / no return 1: mov $1,SSR0 mov nofault,(sp) rtt .globl _runrun, _qswtch call1: tst -(sp) bic $340,PS br 1f call: mov PS,-(sp) 1: mov r1,-(sp) mfpi sp mov 4(sp),-(sp) bic $!37,(sp) bit $30000,PS beq 1f jsr pc,*(r0)+ 2: bis $340,PS tstb _runrun beq 2f bic $340,PS jsr pc,_qswtch br 2b 2: tst (sp)+ mtpi sp br 2f 1: bis $30000,PS jsr pc,*(r0)+ cmp (sp)+,(sp)+ 2: mov (sp)+,r1 tst (sp)+ mov (sp)+,r0 rtt .globl _savfp, _display _savfp: _display: rts pc .globl _incupc _incupc: mov r2,-(sp) mov 6(sp),r2 / base of prof with base,leng,off,scale mov 4(sp),r0 / pc sub 4(r2),r0 / offset clc ror r0 mul 6(r2),r0 / scale ashc $-14.,r0 inc r1 bic $1,r1 cmp r1,2(r2) / length bhis 1f add (r2),r1 / base mov nofault,-(sp) mov $2f,nofault mfpi (r1) inc (sp) mtpi (r1) br 3f 2: clr 6(r2) 3: mov (sp)+,nofault 1: mov (sp)+,r2 rts pc / Character list get/put .globl _getc, _putc .globl _cfreelist _getc: mov 2(sp),r1 mov PS,-(sp) mov r2,-(sp) bis $340,PS bic $40,PS / spl 6 mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ / count bne 1f clr (r1)+ clr (r1)+ / last block br 2f 1: bit $7,r2 bne 3f mov -10(r2),(r1) / next block add $2,(r1) 2: dec r2 bic $7,r2 mov _cfreelist,(r2) mov r2,_cfreelist 3: mov (sp)+,r2 mov (sp)+,PS rts pc 9: clr 4(r1) mov $-1,r0 mov (sp)+,r2 mov (sp)+,PS rts pc _putc: mov 2(sp),r0 mov 4(sp),r1 mov PS,-(sp) mov r2,-(sp) mov r3,-(sp) bis $340,PS bic $40,PS / spl 6 mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist clr (r2)+ mov r2,2(r1) / first ptr br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3 beq 9f mov (r3),_cfreelist mov r3,-10(r2) mov r3,r2  clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) / count clr r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc 9: mov pc,r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc .globl _backup .globl _regloc _backup: mov 2(sp),ssr+2 mov r2,-(sp) jsr pc,backup mov r2,ssr+2 mov (sp)+,r2 movb jflg,r0 bne 2f mov 2(sp),r0 movb ssr+2,r1 jsr pc,1f movb ssr+3,r1 jsr pc,1f movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 2: rts pc 1: mov r1,-(sp) asr (sp) asr (sp) asr (sp) bic $!7,r1 movb _regloc(r1),r1 asl r1 add r0,r1 sub (sp)+,(r1) rts pc / hard part / simulate the ssr2 register missing on 11/40 backup: clr r2 / backup register ssr1 mov $1,bflg / clrs jflg mov ssr+4,r0 jsr pc,fetch mov r0,r1 ash $-11.,r0 bic $!36,r0 jmp *0f(r0) 0: t00; t01; t02; t03; t04; t05; t06; t07 t10; t11; t12; t13; t14; t15; t16; t17 t00: clrb bflg t10: mov r1,r0 swab r0 bic $!16,r0 jmp *0f(r0) 0: u0; u1; u2; u3; u4; u5; u6; u7 u6: / single op, m[tf]pi, sxt, illegal bit $400,r1 beq u5 / all but m[tf], sxt bit $200,r1 beq 1f / mfpi bit $100,r1 bne u5 / sxt / simulate mtpi with double (sp)+,dd bic $4000,r1 / turn instr into (sp)+ br t01 / simulate mfpi with double ss,-(sp) 1: ash $6,r1 bis $46,r1 / -(sp) br t01 u4: / jsr mov r1,r0 jsr pc,setreg / assume no fault bis $173000,r2 / -2 from sp rts pc t07: / EIS clrb bflg u0: / jmp, swab u5: / single op mov r1,r0 br setreg t01: / mov t02: / cmp t03: / bit t04: / bic t05: / bis t06: / add t16: / sub clrb bflg t11: / movb t12: / cmpb t13: / bitb t14: / bicb t15: / bisb mov r1,r0 ash $-6,r0 jsr pc,setreg swab r2 mov r1,r0 jsr pc,setreg / if delta(dest) is zero, / no need to fetch source bit $370,r2 beq 1f / if mode(source) is R, / no fault is possible bit $7000,r1 beq 1f / if reg(source) is reg(dest), / too bad. mov r2,-(sp) bic $174370,(sp) cmpb 1(sp),(sp)+ beq t17 / start source cycle / pick up value of reg mov r1,r0 ash $-6,r0 bic $!7,r0 movb _regloc(r0),r0 asl r0 add ssr+2,r0 mov (r0),r0 / if reg has been incremented, / must decrement it before fetch bit $174000,r2 ble 2f dec r0 bit $10000,r2 beq 2f dec r0 2: / if mode is 6,7 fetch and add X(R) to R bit $4000,r1 beq 2f bit $2000,r1 beq 2f mov r0,-(sp) mov ssr+4,r0 add $2,r0 jsr pc,fetch add (sp)+,r0 2: / fetch operand / if mode is 3,5,7 fetch * jsr pc,fetch bit $1000,r1 beq 1f bit $6000,r1 bne fetch 1: rts pc t17: / illegal u1: / br u2: / br u3: / br u7: / illegal incb jflg rts pc setreg: mov r0,-(sp) bic $!7,r0 bis r0,r2 mov (sp)+,r0 ash $-3,r0 bic $!7,r0 movb 0f(r0),r0 tstb bflg beq 1f bit $2,r2 beq 2f bit $4,r2 beq 2f 1: cmp r0,$20 beq 2f cmp r0,$-20 beq 2f asl r0 2: bisb r0,r2 rts pc 0: .byte 0,0,10,20,-10,-20,0,0 fetch: bic $1,r0 mov nofault,-(sp) mov $1f,nofault mfpi (r0) mov (sp)+,r0 mov (sp)+,nofault rts pc 1: mov (sp)+,nofault clrb r2 / clear out dest on fault mov $-1,r0 rts pc .bss bflg: .=.+1 jflg: .=.+1 .text .globl _fubyte, _subyte .globl _fuibyte, _suibyte .globl _fuword, _suword .globl _fuiword, _suiword _fuibyte: _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword cmp r1,2(sp) beq 1f swab r0 1: bic $!377,r0 rts pc _suibyte: _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,pword clr r0 rts pc _fuiword: _fuword: mov 2(sp),r1 fuword: jsr pc,gword rts pc gword: mov PS,-(sp) bis $340,PS mov nofault,-(sp) mov $err,nofault mfpi (r1) mov (sp)+,r0 br 1f _suiword: _suword: mov 2(sp),r1 mov 4(sp),r0 suword: jsr pc,pword rts pc pword: mov PS,-(sp) bis $340,PS mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpi (r1) 1: mov (sp)+,nofault mov (sp)+,PS rts pc err: mov (sp)+,nofault mov (sp)+,PS tst (sp)+ mov $-1,r0 rts pc .globl _copyin, _copyout .globl _copyiin, _copyiout _copyiin: _copyin: jsr pc,copsu 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyiout: _copyout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpi (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 14(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc .globl _idle, _waitloc _idle: mov PS,-(sp) bic $340,PS wait _waitloc: mov (sp)+,PS rts pc .globl _savu, _retu, _aretu _savu: bis $340,PS mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ bic $340,PS jmp (r1) _aretu: bis $340,PS mov (sp)+,r1 mov (sp),r0 br 1f _retu: bis $340,PS mov (sp)+,r1 mov (sp),KISA6 mov $_u,r0 1: mov (r0)+,sp mov (r0)+,r5 bic $340,PS jmp (r1) .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: bic $340,PS rts pc _spl1: bis $40,PS bic $300,PS rts pc _spl4: _spl5: bis $340,PS bic $100,PS rts pc _spl6: bis $340,PS bic $40,PS rts pc _spl7: bis $340,PS rts pc .globl _copyseg _copyseg: mov PS,-(sp) mov UISA0,-(sp) mov UISA1,-(sp) mov $30340,PS mov 10(sp),UISA0 mov 12(sp),UISA1 mov UISD0,-(sp) mov UISD1,-(sp) mov $6,UISD0 mov $6,UISD1 mov r2,-(sp) clr r0 mov $8192.,r1 mov $32.,r2 1: mfpi (r0)+ mtpi (r1)+ sob r2,1b mov (sp)+,r2 mov (sp)+,UISD1 mov (sp)+,UISD0 mov (sp)+,UISA1 mov (sp)+,UISA0 mov (sp)+,PS rts pc .globl _clearseg _clearseg: mov PS,-(sp) mov UISA0,-(sp) mov $30340,PS mov 6(sp),UISA0 mov UISD0,-(sp) mov $6,UISD0 clr r0 mov $32.,r1 1: clr -(sp) mtpi (r0)+ sob r1,1b mov (sp)+,UISD0 mov (sp)+,UISA0 mov (sp)+,PS rts pc .globl _dpadd _dpadd:  mov 2(sp),r0 add 4(sp),2(r0) adc (r0) rts pc .globl _dpcmp _dpcmp: mov 2(sp),r0 mov 4(sp),r1 sub 6(sp),r0 sub 8(sp),r1 sbc r0 bge 1f cmp r0,$-1 bne 2f cmp r1,$-512. bhi 3f 2: mov $-512.,r0 rts pc 1: bne 2f cmp r1,$512. blo 3f 2: mov $512.,r1 3: mov r1,r0 rts pc .globl dump dump: bit $1,SSR0 bne dump / save regs r0,r1,r2,r3,r4,r5,r6,KIA6 / starting at abs location 4 mov r0,4 mov $6,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ mov KISA6,(r0)+ / dump all of core (ie to first mt error) / onto mag tape. (9 track or 7 track 'binary') .if .mt mov $MTC,r0 mov $60004,(r0)+ clr 2(r0) 1: mov $-512.,(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset mov $60007,-(r0) br . .endif .if .mt-1 mov $TUC,r0 mov $60,(r0)+ clr 2(r0) clr 6(r0) mov $1300,24.(r0) / 800 bpi, pdp11 mode, unit zero 1: mov $-256.,(r0) mov $512.,4(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset mov $027,-(r0) br . .endif .globl start, _end, _edata, _main start: bit $1,SSR0 bne start / loop if restart reset / Set loc. 0 to trap to system, in case of / hardware glitch mov $trap,0 mov $340+15.,2 / initialize systems segments mov $KISA0,r0 mov $KISD0,r1 mov $200,r4 clr r2 mov $6,r3 1: mov r2,(r0)+ mov $77406,(r1)+ / 4k rw add r4,r2 sob r3,1b / initialize user segment mov $_end+63.,r2 ash $-6,r2 bic $!1777,r2 mov r2,(r0)+ / ksr6 = sysu mov $usize-1\<8|6,(r1)+ / initialize io segment / set up counts on supervisor segments mov $IO,(r0)+ mov $77406,(r1)+ / rw 4k / get a sp and start segmentation mov $_u+[usize*64.],sp inc SSR0 / clear bss mov $_edata,r0 1: clr (r0)+ cmp r0,$_end blo 1b / clear user block mov $_u,r0 1: clr (r0)+ cmp r0,$_u+[usize*64.] blo 1b / set up previous mode and call main / on return, enter user mode at 0R mov $30000,PS jsr pc,_main mov $170000,-(sp) clr -(sp) rtt .globl _ldiv _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc .globl _lrem _lrem: clr r0 mov 2(sp),r1 div 4(sp),r0 mov r1,r0 rts pc .globl _lshift _lshift: mov 2(sp),r1 mov (r1)+,r0 mov (r1),r1 ashc 4(sp),r0 mov r1,r0 rts pc .globl csv csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) .globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc .globl _u _u = 140000 usize = 16. PS = 177776 SSR0 = 177572 SSR2 = 177576 KISA0 = 172340 KISA6 = 172354 KISD0 = 172300 MTC = 172522 TUC = 172440 UISA0 = 177640 UISA1 = 177642 UISD0 = 177600 UISD1 = 177602 IO = 7600 .data .globl _ka6, _cputype _ka6: KISA6 _cputype:40. .bss .globl nofault, ssr, badtrap nofault:.=.+2 ssr: .=.+6 badtrap:.=.+2 .globl _mapalloc .globl _msginit .globl _serrlog .globl _lflags globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc .globl _u _u = 140000 usize = 16. PS = 177776 SSR0 = 177572 SSR2 = 177576 KISA0 = 172340 KISA6 = 172354 KISD0 = 172300 MTC = 172522 TUC = 172440 UISA0 = 177640 UISA1 = 177642 UISD! "W N F=    @ #D  D ҃TT ^ B ы e@W 0 ,"& 7    " 7 -  X e5PߋRTV`RߋR RT `Re `R7 t*p ȋ@E A Ze   ?    7? eEfc1/f11.s7C s?fc1/f12.sC tCfc1/f13.sC uFfc1/f14.syC vI:fc1/f15.sC yL-fc1/f16.swC zN1fc1/f17.sC {Ofc2/f21.sC }Qfc2/f22.sC ~Rfc2/f23.sC Ufc2/f24.sp C Y'fc3/f31.sC _fc3/f32.s C cfc3/f33.sPC h3fc3/f34.sC lfc3/f35.sC ndfc3/f36.sC qƪfc3/f37.sMC }fc3/f38.sC wfc3/f39.s C fc4/f41.sC |fc4/f42.sC fc4/f43.sC fc4/f44.sC xfc4/f45.sBC fc4/f46.sC fc4/f47.shC fcio/io1.sC Ifcio/io2.s C fcio/io3.s' C fcio/io4.sC ;fcio/io5.sC fcio/io6.s C fcio/io7.sC ffcio/iox.s7C ˛fclib1/abs.sC ө~fclib1/aimag.sC ԩyfclib1/aint.sC թ+fclib1/alog.sC ֩fclib1/alog10.s6C שlfclib1/amax0.sC ةs_fclib1/amax1.sC ٩^fclib1/amin0.sC کyWfclib1/amin1.sC ۩;Vfclib1/amod.sNC ܩ|fclib1/atan.sC ݩfclib1/atan2.s'C ީ]fclib2/cabs.s!C fclib2/ccos.fC fclib2/cexp.fC fclib2/clog.fC fclib2/cmplx.s7C fclib2/conjg.sC +fclib2/cos.sC {fclib2/csin.fC fclib2/csqrt.fC fclib2/dble.sC fclib2/dccos.fC #fclib2/dcexp.fC %fclib2/dclog.fC 'fclib2/dcsin.fC fclib2/dcsqrt.fC ALfclib2/dim.sC jfclib2/dimag.sC >fclib2/exp.sC =|fclib3/float.sC 2fclib3/iabs.sC fclib3/idim.sC fclib3/idint.sC H fclib3/ierr.sC fclib3/ifix.sC fclib3/isign.sC fclib3/mod.sC fclib3/real.sC fclib3/sign.s)C Wfclib3/sin.sC `ofclib3/sngl.sC ˺fclib3/sqrt.sC jfclib3/tanh.fKC Hfclib4/ctime.sC fclib4/errorsC sfclib4/getarg.sC bCfclib4/nice.sC fclib4/openrw.sC eKfclib4/orand.sC fclib4/plot.sC fclib4/rand.sC fclib4/rio.sfC lfclib4/setfil.sC eBfclib4/sleep.sC fclib4/uio.s C bfcrt/r0.sC Ifcrt/r1.sC Gfcrt/r2.sC Gfcrt/r3.sC Kfcrt/r4.sjC ©-Jfcrt/r5.sC éJfcrt/r6.s!C ĩoHfcrt/r7.s&C ũeGfcrt/r8.s!C ƩeKfcrt/r9.s7C ǩLJfcrt/ra.soC ȩJfcrt/rb.sC ɩGfcrt/rc.sD C ʩ Afcrt/rd.suC ˩%Jfcrt/re.sC ̩&TJfcrt/rf.sC Ω'`Jfcrt/rg.sC ϩ(Hfcrt/rh.sbC Щ*Ffcrt/rx.s8C ѩ-Kfcsub/fhd.sC .G"fcsub/fx1.sC 07fcsub/fx2.sxC 1fcsub/fx3.sC 4fcsub/fx4.s C 6fcsub/fx5.sC ?fcsub/fx6.sC Afcsub/fx7.sC Bfcsub/fx8.s C C@ fcsub/fx9.s#C Ifcsub/fxa.sC Lfcsub/fxb.s<C Mqfcsub/fxc.slC N>fcsub/fxd.sC Ofcsub/fxe.sC Pfcsub/fxf.sC Qfcsub/fxg.s C R fcsub/fxh.sC Xyfcsub/fxi.sC [fcsub/fxx.sC ^sccscmds/chghist.c  _d`sccshead/sint.hS bfsccsutil1/bufrd.cF jrsccsutil1/bufwrt.cB l#sccsutil1/cat.c nsccsutil1/cindex.c oosccsutil1/clean.cl psccsutil1/copy.c q?sccsutil1/dblgtr.c> r sccsutil1/dname.cQ ssccsutil1/dsize.c u osccsutil1/alloc.c vR{sccsutil1/equal.c zsccsutil1/gt.cv {sccsutil1/exists.c |Gsccsutil1/exit1.c~ }psccsutil1/exit2.c ~psccsutil1/fatal.c  ߖsccsutil1/getchr.c \sccsutil1/getl.c Rsccsutil1/getldr.c$ sccsutil1/getlnm.c( sccsutil2/msg2.c[ sccsutil2/patoi.cT psccsutil2/putchr.si sccsutil2/putl.c Csccsutil2/pwldir.c 2sccsutil2/remove.c sccsutil2/rename.cB sccsutil2/same.c4 asccsutil2/move.c Rsccsutil2/setsig.c  sccsutil2/xwrite.c  sccsutil2/size.c Ysccsutil2/sname.c+ }sccsutil2/strf.c Lsccsutil2/substr.c sccsutil2/xcreat.c| Csccsutil2/xlink.c sccsutil2/xopen.c  Vsccsutil2/xpipe.c {/ / / f11 -- fortran command / .globl pass1 .globl fptrap .globl getline .globl flush .globl perror .globl lookup .globl getype .globl ssubr .globl sfunc .globl sbloc .globl sextr .globl sdime .globl scomm .globl sequi .globl sdata .globl sform .globl simpl .globl stype .globl isagn .globl ptemp .globl funok .globl signoff .globl fopen .globl fcreat .globl lookid .globl tfil1, tfil2 .globl tfildiag pass1: sys signal; 4; fptrap cmp (sp)+,$2 bge 1f 2: mov $1,r0 sys write; mes2; emes2-mes2 clr r0 sys seek; 0; 2 mov $-1,r0 / bad status sys exit 1: tst (sp)+ mov (sp)+,r0 jsr r5,fopen; ibuf bcs 2b mov $tfil1,r0 jsr r5,fcreat; obuf bcs 2f mov $tfil2,r0 jsr r5,fcreat; tbuf bcc 1f 2: jmp tfildiag 1: / data segment initialization mov $2,nxtaloc mov $errb,errp mov $esymtab,esymp mov $namebuf,namep movb $'_,symbuf-1 jsr r5,lookid; blankc bis $40,symtab(r3) mov $imptab,r3 1: mov $realcon,r0 / real*4 cmp r3,$imptab+[2*['i-'a]] blo 2f cmp r3,$imptab+[2*['n-'a]] bhi 2f mov $intcon,r0 / integer*4 2: mov r0,[2*26.](r3) / lower case mov r0,(r3)+ / upper case cmp r3,$imptab+[2*26.] blo 1b / call pass1 / main scan loop for pass1 / picks up non executable statements / scan1: jsr r5,getline mov $line,r1 jsr r5,isagn br 2f mov r1,r2 jsr r5,lookup; stmtab br 1f mov r2,r1 jsr r5,*sublst(r0) mov pc,funok jsr r5,perror br scan1 1: jsr r5,getype br 2f mov r2,r1 jsr r5,stype jsr r5,perror mov pc,funok br scan1 2: jsr r5,ptemp; 'l; efno; line jsr r5,flush; tbuf jsr r5,signoff; 1 sublst: ssubr sfunc sbloc sextr sdime scomm sequi sdata sform simpl stmtab: <\0> .even mes2: emes2: blankc: <_\n\0> .even 5,*sublst(r0) mov pc,funok jsr r5,perror br scan1 1: jsr r5,getype br 2f mov r2,r1 jsr r5,stype jsr r5,perror mov pc,funok br scan1 2: jsr r5,ptemp; 'l; efno; line jsr r5,flush; tbuf jsr / / / f12 -- type statements and type getter subroutine / / .globl stype .globl getype .globl typtab .globl sfunc1 .globl lookup .globl getsym .globl error .globl sdime1 stype: mov r0,-(sp) mov r1,r2 jsr r5,lookup; funtab br 1f mov r2,r1 mov (sp)+,r0 jmp sfunc1 1: jsr r5,getsym tst r0 bne 3f / junk error if not identifier mov symtab(r3),r0 bic $![377\<8+7],r0 / size,type beq 2f cmp r0,(sp) / redefined, but same beq 2f jsr r5,error; 3. 2: bic $377\<8+7,symtab(r3) bis (sp),symtab(r3) / set in type and size mov r3,-(sp) jsr r5,getsym cmp r0,$32. / ( for dimension bne 2f mov (sp),r3 jsr r5,sdime1 jsr r5,getsym 2: tst (sp)+ cmp r0,$36. / , for another list element beq 1b cmp r0,$40. / eos beq 1f 3: jsr r5,error; 2. / junk 1: tst (sp)+ rts r5 funtab: <\0> getype: mov r1,r2 jsr r5,lookup; typtab br 1f mov tvaltab(r0),r0 tst (r5)+ 1: rts r5 tvaltab: log1con logcon int1con int2con intcon dcplxcon dblcon cplxcon dblcon realcon undefcon typtab: <\0> another list element beq 1b cmp r0,$40. / eos beq 1f 3: jsr r5,error; 2. / junk 1: tst (sp)+ rts r5 funtab: <\0> getype: mov r1,r2 jsr r5,lookup; typtab br 1f mov tvaltab(r0),r0 tst (r5)+ 1: rts r5 tvaltab: log1con logcon int1con int2con intcon dcplxcon dblcon cplxcon dblcon realcon undefcon typt/ / / f13 -- dimension and array declarator / / dimension / / .globl sdime .globl sdime1 .globl getsym .globl error .globl geti .globl dimu sdime: jsr r5,getsym tst r0 bne 3f / junk error mov r3,-(sp) jsr r5,getsym mov (sp)+,r3 cmp r0,$32. / ( beq 2f jsr r5,error; 4. / no ( in dimension rts r5 2: jsr r5,sdime1 jsr r5,getsym cmp r0,$36. / , beq sdime cmp r0,$40. beq 1f 3: jsr r5,error; 5. 1: rts r5 / get dimension info and store in / symbol table entry / r3 points at symbol table / r1 points just beyond ( sdime1: bit $70,symtab(r3) / class beq 1f jsr r5,error; 6. / already classed 1: mov r3,-(sp) bic $70,symtab(r3) bis $20,symtab(r3) / set as array clr -(sp) / marker 1: jsr r5,getsym cmp r0,$2 / constant bne 2f cmp r3,$intcon / integer*4 bne 3f jsr r5,geti tst r0 ble 3f mov r0,-(sp) br 4f 2: tst r0 bne 3f / identifer tstb symtab(r3) bge 3f / not parameter neg r3 mov r3,-(sp) mov sp,r0 2: tst (r0)+ bne 2b mov (r0),r0 tstb symtab(r0) bge 3f / array not a param 4: jsr r5,getsym cmp r0,$36. / , beq 1b cmp r0,$34. / ) beq 1f 3: jsr r5,error; 7. 1: mov esymp,r0 clr r2 mov dimu,-(r0) inc dimu / unique number 1: inc r2 mov (sp)+,-(r0) bne 1b dec r2 mov r2,(r0) mov r0,esymp mov (sp)+,r3 mov r0,symtab+2(r3) rts r5 jsr r5,geti tst r0 ble 3f mov r0,-(sp) br 4f 2: tst r0 bne 3f / identifer tstb symtab(r3) bge 3f / not parameter neg r3 mov r3,-(sp) mov sp,r0 2: tst (r0)+ bne 2b mov (r0),r0 tstb symtab(r0) bge 3f / array not a/ / / f14 -- common statement / .globl scomm .globl getsym .globl sdime1 .globl error .globl getid .globl lookid scomm: mov r5,-(sp) jsr r5,getsym cmp r0,$6 / / for named common beq ncom 3: tst r0 bne 9f mov r3,-(sp) clr r5 br 2f ncom: cmpb (r1),$'/ bne 3f inc r1 jsr r5,getsym br 3b 3: jsr r5,getid br 9f / not identifier jsr r5,lookid; symbuf-1 bis $40,symtab(r3) / set named common mov r3,r5 jsr r5,getsym cmp r0,$6 / / bne 9f 1: jsr r5,getsym tst r0 bne 9f mov r3,-(sp) 2:  jsr r5,getsym cmp r0,$32. / ( bne 2f mov (sp),r3 jsr r5,sdime1 jsr r5,getsym 2: mov (sp)+,r3 bit $300,symtab(r3) / test param/common beq 2f jsr r5,error; 9. / not commonable or already commoned br 3f 2: mov r0,-(sp) mov symtab+4(r5),r0 beq 2f mov r3,symtab+4(r0) / next ptr of old last block 2: mov (sp)+,r0 mov r3,symtab+4(r5) / new last ptr of head block tst symtab+2(r5) bne 3f mov r3,symtab+2(r5) / first ptr if first block 3: bis $100,symtab(r3) cmp r0,$36. / , beq 1b cmp r0,$6 / another / beq ncom cmp r0,$40. / =| beq 8f 9: jsr r5, error; 10. / common syntax error 8: mov (sp)+,r5 rts r5 / test param/common beq 2f jsr r5,error; 9. / not commonable or already commoned br 3f 2: mov r0,-(sp) mov symtab+4(r5),r0 beq 2f mov r3,symtab+4(r0) / next ptr of old last block 2: mov (sp)+,r0 mov r3,symtab+4(r5) / new last ptr of head block tst symtab+2(r5) bne 3f mov r3,symtab+2(r5) / first ptr if first block 3: bis $100,symtab(r3) cmp r0,$36. / , beq 1b cmp r0,$6 // / / f15 -- subroutine/function .globl ssubr .globl sfunc .globl sbloc .globl sfunc1 .globl funok .globl getsym .globl error ssubr: mov $2,progt br 1f sfunc: mov $4,progt 1: clr r0 br 2f sfunc1: mov $4,progt 2: tst funok beq 1f jsr r5,error; 11. 1: add $10,r0 / class=simple mov r0,-(sp) jsr r5,getsym mov (sp)+,r2 tst r0 beq 1f 2: jsr r5,error; 12. rts r5 1: mov r2,symtab(r3) jsr r5,getsym cmp r0,$32. / ( beq 1f cmp r0,$40. / eos bne 2b rts r5 1: clr -(sp) 1: add $2,(sp) jsr r5,getsym tst r0 beq 3f tst (sp)+ br 2b 3: bis $200,symtab(r3) / param mov (sp),symtab+6(r3) / param number jsr r5,getsym cmp r0,$36. / , beq 1b tst (sp)+ cmp r0,$34. / ) bne 2b jsr r5,getsym cmp r0,$40. bne 2b rts r5 sbloc: mov $6,progt jsr r5,getsym tst funok beq 1f jsr r5,error; 11. 1: cmp r0,$40. beq 1f jsr r5,error; 13. 1: rts r5 .data funok: 0 : mov r2,symtab(r3) jsr r5,getsym cmp r0,$32. / ( beq 1f cmp r0,$40. / eos bne 2b rts r5 1: clr -(sp) 1: add $2,(sp) j/ / / f16 -- extrn, equiv, data .globl sextr .globl sequi .globl getsym .globl putc .globl error .globl ptemp sextr: jsr r5,getsym tst r0 bne 1f bit $70,symtab(r3) beq 2f jsr r5,error; 14. 2: bis $30,symtab(r3) jsr r5,getsym cmp r0,$36. / , beq sextr cmp r0,$40. / eos beq 2f 1: jsr r5,error; 15. 2: rts r5 sequi: jsr r5,ptemp; 'e; efno; line rts r5 unok: 0 : mov r2,symtab(r3) jsr r5,getsym cmp r0,$32. / ( beq 1f cmp r0,$40. / eos bne 2b rts r5 1: clr -(sp) 1: add $2,(sp) j/ / / f17 -- implicit statement .globl simpl .globl getype .globl chrtab .globl error simpl: jsr r5,getype br 9f mov r2,r1 mov r0,-(sp) movb (r1)+,r0 cmp r0,$'( beq 1f cmpb r0,$'/ bne 8f 1: movb (r1)+,r0 cmpb chrtab(r0),$2 bne 8f cmpb r0,$'a blo 2f sub $6,r0 / map 'a into 'Z+1 2: movb (r1)+,r2 cmpb r2,$'- bne 2f movb (r1)+,r2 cmpb chrtab(r2),$2 bne 8f cmp r2,$'a blo 3f sub $6,r2 / map 'a into 'Z+1 br 3f 2: mov r0,r2 dec r1 3: cmp r0,r2 bhi 8f asl r0 asl r2 3: mov (sp),imptab-[2*'A](r0) add $2,r0 cmp r0,r2 blos 3b movb (r1)+,r0 cmp r0,$', beq 1b tst (sp)+ cmp r0,$') beq 1f cmp r0,$'/ bne 9f 1: tstb (r1) bne simpl rts r5 8: tst (sp)+ 9: jsr r5,error; 16. / implicit syntax error rts r5 2 bne 8f cmpb r0,$'a blo 2f sub $6,r0 / map 'a into 'Z+1 2: movb (r1)+,r2 cmpb r2,$'- bne 2f movb (r1)+,r2 cmpb chrtab(r2),$2 bne 8f cmp r2,$'a blo 3f sub $6,r2 / map 'a into 'Z+1 br 3f 2: mov r0,r2 dec r1 3: cmp r0,r2 bhi 8f asl r0 asl r2 3: mov (sp),/ / / f21 -- storage allocation / .globl pass2 .globl signon .globl signoff .globl calloc .globl salloc .globl equiv .globl entry pass2: jsr r5,signon; 2 mov $errb,errp jsr r5,calloc jsr r5,equiv jsr r5,salloc jsr r5,entry jsr r5,signoff; 2 r0,$'a blo 2f sub $6,r0 / map 'a into 'Z+1 2: movb (r1)+,r2 cmpb r2,$'- bne 2f movb (r1)+,r2 cmpb chrtab(r2),$2 bne 8f cmp r2,$'a blo 3f sub $6,r2 / map 'a into 'Z+1 br 3f 2: mov r0,r2 dec r1 3: cmp r0,r2 bhi 8f asl r0 asl r2 3: mov (sp),/ / / f22 -- allocate common .globl calloc .globl entry .globl declimpl .globl size .globl getc .globl getw .globl xbuf .globl code .globl typ calloc: clr r3 1: cmp r3,symtp bhis 1f mov symtab(r3),r0 bic $!70,r0 / class cmp r0,$40 / common block bne 3f mov r3,-(sp) mov symtab+2(r3),r3 clr r2 / byte offset 2: tst r3 beq 2f jsr r5,declimpl mov symtab+4(r3),-(sp) mov 2(sp),symtab+4(r3) mov r2,symtab+6(r3) jsr r5,size add r0,r2 mov (sp)+,r3 br 2b 2: mov (sp)+,r3 clr symtab+2(r3) mov r2,symtab+6(r3) / common block size 3: add $8,r3 br 1b 1: rts r5 entry: mov progt,r0 jmp *1f(r0) 1: main subr funct blocd main: jsr r5,code ; .even rts r5 subr: funct: jsr r5,code <%n.: %n_\n\0>; .even 8 8 jsr r5,code < entry; name\n\0>; .even clr r3 1: cmp r3,symtp bhis 1f mov symtab+2(r3),r0 beq 2f mov (r0)+,r1 / num dims asl r1 add r0,r1 / ptr to last dim mov r3,-(sp) mov (r1),-(sp) / dope id clr r2 / dope offset 3: add $2,r2 mov -(r1),r3 cmp r0,r1 bhi 3f neg r3 / adjustable dimension ble 3b mov r0,-(sp) jsr r5,declimpl mov symtab(r3),r0 clrb r0 swab r0 jsr r5,code < rval%dp; %n_\n\0>; .even r0 r3 mov symtab(r3),r3 bic $![377\<8+7],r3 cmp r3,$2\<8+1 / is it i*2 beq 4f bic $!7,r3 movb typ(r3),r3 jsr r5,code < %c%di2\n\0>; .even r3 r0 4: mov 2(sp),r0 jsr r5,code < stst; d%d+%d.\n\0>; .even r0 r2 mov (sp)+,r0 br 3b 3: tst (sp)+ mov (sp)+,r3 2: add $8,r3 br 1b 1: blocd: rts r5 d $2,r2 mov -(r1),r3 cmp r0,r1/ / / f23 -- do equivalence statements .globl equiv .globl getsym .globl consub .globl eqvtab .globl error .globl declimpl .globl perror .globl setln .globl getln / equivalence statements, part 1 / destroys all registers equiv: jsr r5,setln 1: jsr r5,getln rts r5 cmp r0,$'e bne 1b mov $line+11.,r1 mov r5,-(sp) 2: / start equivalence group cmpb (r1)+,$'( / check ( bne 9f / syntax error jsr r5,getsym tst r0 bne 9f / not identifier mov r3,r5 jsr r5,equset movb (r1)+,r2 clr r4 / offset cmp r2,$', beq 3f cmp r2,$'( / subscripted vble bne 9f / syntax error jsr r5,consub / get subscript mov r0,r4 cmpb (r1)+,$', bne 9f 3: / rest of group jsr r5,getsym / next ident tst r0 bne 9f / syntax jsr r5,equset clr r0 mov r3,r2 cmpb (r1),$'( / subscript? bne 4f inc r1 jsr r5,consub 4: mov eqvtab+2(r2),r2 cmp r2,r5 beq 5f / already in same group cmp r2,r3 bne 4b / not yet in different group sub r4,r0 / adjust offsets sub eqvtab+4(r5),r0 / left vble's offset add eqvtab+4(r3),r0 / new vble's offset 4: sub r0,eqvtab+4(r2) mov eqvtab+2(r2),r2 cmp r2,r3 bne 4b mov eqvtab+2(r3),r0 / link up groups mov eqvtab+2(r5),eqvtab+2(r3) mov r0,eqvtab+2(r5) / link groups br 6f 5: / here already in same group cmp r0,r4 / offset must be same beq 6f jsr r5,error; 23. / inconsistency! 6: movb (r1)+,r0 cmp r0,$', beq 3b cmp r0,$') bne 9f movb (r1)+,r0 bne 3f jsr r5,perror mov (sp)+,r5 br 1b 3: cmp r0,$', beq 2b 9: jsr r5,error; 24. / equivalence syntax jsr r5,perror mov (sp)+,r5 br 1b / initialize member of equivalence group equset: jsr r5,declimpl / declare if necessary mov symtab(r3),r0 bit $200,r0 / test parameter bne 2f bic $!70,r0 cmp r0,$10 / simple beq 1f cmp r0,$20 / array beq 1f 2: jsr r5,error; 31. / non-equivalencable variable 1: tst eqvtab+2(r3) / see if mentioned yet bne 1f mov r3,eqvtab+2(r3) / points to itself 1: rts r5 or mov (sp)+,r5 br 1b 3: cmp r0,$', beq 2b 9: jsr r5,error; 24. / equival/ / / f24 -- allocate storage for non-common variables / called after common and equivalence have been done .globl salloc .globl eqvtab .globl error .globl declimpl .globl size .globl perror / destroys all registers salloc: mov r5,-(sp) clr r3 / loop over symbol table br 2f 1: add $8.,r3 / next variable 2: cmp r3,symtp blo 2f mov (sp)+,r5 mov $line,r1 jsr r5,perror / flush errors rts r5 2: bit $70,symtab(r3) beq 1b / unclassed jsr r5,declimpl / just in case tst eqvtab(r3) / test for already allocated bne 1b / yes mov symtab(r3),r0 bic $!70,r0 cmp r0,$10 / test class=simple beq 2f cmp r0,$20 / test array bne 1b / no, not a variable 2: bit $200,symtab(r3) / test parameter bne 1b tst eqvtab+2(r3) / test for equivalence bne 2f / yes bit $100,symtab(r3) / test common bne 1b / yes, nothing to do mov nxtaloc,symtab+6(r3) / offset jsr r5,size / get byte count add r0,nxtaloc inc eqvtab(r3) / mark allocated br 1b 2: clr r4 / common variable of group mov $77777,r1 / infinity to smallest offset mov r3,r5 2: cmp eqvtab+4(r3),r1 bgt 3f mov eqvtab+4(r3),r1 / replace smallest offset 3: bit $100,symtab(r3) / test common beq 3f mov r3,r4 / yes 3: mov eqvtab+2(r3),r3 / next group member cmp r3,r5 bne 2b tst r4 bne 2f / *there was a common in group / equivalence group w/o common sub nxtaloc,r1 / get -(group offset) 3: inc eqvtab(r3) / mark allocated mov eqvtab+4(r3),r2 sub r1,r2 / compute offset mov r2,symtab+6(r3) / enter offset jsr r5,size add r0,r2 / highest loc of variable cmp r2,r4 ble 4f mov r2,r4 / extends storage 4: mov eqvtab+2(r3),r3 / next of group cmp r3,r5 bne 3b mov r4,nxtaloc / account for space br 1b / done! 2: / equivalence group w/ common mov symtab+6(r4),r1 / actual common offset sub eqvtab+4(r4),r1 / virtual common offset 2: inc eqvtab(r3) / mark allocated bit $100,symtab(r3) / is variable already in common beq 3f / *no cmp symtab+4(r4),symtab+4(r3) beq 4f jsr r5,error; 25. / different blocks equiv. 4: mov r1,r0 add eqvtab+4(r3),r0 cmp r0,symtab+6(r3) beq 4f / ok jsr r5,error; 27. / same variable, different offsets br 4f 3: bis $100,symtab(r3) / mark common now mov symtab+4(r4),symtab+4(r3)/ get right common block mov r1,r0 add eqvtab+4(r3),r0 bge 3f jsr r5,error; 26. / block extended leftward clr r0 3: mov r0,symtab+6(r3) / get proper offset mov r0,-(sp) jsr r5,size / see if size is extended add (sp)+,r0 mov symtab+4(r3),r2 / common block cmp symtab+6(r2),r0 bge 4f / ok mov r0,symtab+6(r2) / extend size 4: mov eqvtab+2(r3),r3 cmp r3,r5 bne 2b jmp 1b . / same variable, different offsets br 4f 3: bis $100,symtab(r3) / mark common now mov symtab+4(r4),symtab+4(r3)/ get right common block mov r1,r0 add eqvtab+4(r3),r0 bge 3f jsr r5,error; 26. / block extended leftward clr r0 3: mov r0,symtab+6(r3) / get proper offset mov r0,-(sp) jsr r5,size / see if size is extended add (sp)+,r0 mov symtab+4(r3),r2 / common block cmp symtab+/ / / f31 - pass3 dispatcher / / main scan loop for pass3 / picks up executable statements / .globl pass3 .globl ifstmt .globl isagn .globl signon .globl signoff .globl getline .globl lookup .globl sasgn .globl error .globl perror .globl doend .globl sform .globl sdata .globl sdo .globl sassi .globl scall .globl scont .globl sretu .globl sgoto .globl sif .globl spaus .globl sstop .globl sread .globl sprin .globl swrit .globl srewi .globl sback .globl sendf .globl blocks .globl blockp .globl code .globl ptemp .globl dotabp pass3: jsr r5,signon; 3 br 2f scan3: jsr r5,getline 2: mov $blocks,blockp mov $line,r1 mov r1,r2 jsr r5,lookup; fmttab br 2f mov r0,-(sp) jsr r5,isagn br 1f mov (sp)+,r0 jsr r5,*fmtlst(r0) br scan3 1: tst (sp)+ 2: mov efno,r0 beq 1f jsr r5,ptemp; 's; efno; line jsr r5,code <.%d:\n\0>; .even r0 1: mov ifno,r0 jsr r5,code < lino; %d.\n\0>; .even r0 jsr r5,isagn br 1f mov r1,r2 jsr r5,lookup; stmtab br 2f mov r2,r1 jsr r5,*sublst(r0) br 3f 1: jsr r5,sasgn br 3f 2: jsr r5,error; 101. 3: cmp progt,$6 bne 1f jsr r5,error; 50. / execut in block data 1: jsr r5,perror mov efno,r0 beq scan3 jsr r5,doend br scan3 ifstmt: mov $blocks,blockp jsr r5,isagn br 1f mov r1,r2 jsr r5,lookup; stmtab1 br 2f mov r2,r1 cmp r0,$4 / don't allow end beq 2f jmp *sublst1(r0) 1: jmp sasgn 2: jsr r5,error; 101. rts r5 send: tst dotabp beq 1f clr r0 jsr r5,doend br send 1: tst progt bne 1f jsr r5,sstop br 2f 1: cmp progt,$6 / block data beq 2f jsr r5,sretu 2: jsr r5,perror jsr r5,signoff; 3 sublst: sdo sublst1: sif sendf send sassi scall scont sretu sgoto spaus sstop sread sprin swrit srewi sback fmtlst: sform sdata stmtab: stmtab1: / keep in this spot!!! <\0> fmttab: <\0> .even br 2f 1: cmp progt,$6 / block data be/ / / f32 -- expression to tree .globl e1 .globl e2 .globl e11 .globl error .globl getsym .globl blockp .globl blocks .globl declimpl .globl conu .globl ptemp .globl functn .globl funimpl / e1: e2[,e1] / e2: e2[.or.e3] / e3: e3[.and.e4] / e4: [.not.]e5 / e5: e6[.rel.e6] / e6: [+-]e7[+-e6] / e7: e7[*/e8] / e8: e9[**e9] / e9: constant / name[(e1)] / (e2) e1: jsr r5,e2 cmp r0,$36. / , bne 1f jsr r5,block; e1 rts r5 e2: jsr r5,e3 2: cmp r0,$30. / or bne 1f jsr r5,block; e3 br 2b e3: jsr r5,e4 2: cmp r0,$28. / and bne 1f jsr r5,block; e4 br 2b e4: jsr r5,getsym cmp r0,$26. / not bne e5 clr r2 jsr r5,block; e5a rts r5 e5a: jsr r5,getsym e5: jsr r5,e6 cmp r0,$14. / .lt. blo 1f cmp r0,$24. / .ge. bhi 1f jsr r5,block; e6a rts r5 e6a: jsr r5,getsym e6: cmp r0,$12. / + beq e6a cmp r0,$10. / - bne 2f clr r2 jsr r5,block; e7a br 3f 2: jsr r5,e7 3: cmp r0,$10. / - blo 1f cmp r0,$12. / + bhi 1f jsr r5,block; e7a br 3b e7a: jsr r5,getsym e7: jsr r5,e8 2: cmp r0,$6. / / blo 1f cmp r0,$8. / * bhi 1f jsr r5,block; e8a br 2b e8a: jsr r5,getsym e8: jsr r5,e9 cmp r0,$4 / ** bne 1f jsr r5,block; e9a 1: rts r5 e9a: jsr r5,getsym e9: cmp r0,$2 / constant beq 3f / (e2) cmp r0,$32. / ( bne 1f jsr r5,e2 br 2f e10: jsr r5,e1 2: cmp r0,$34. / ) beq 2f jsr r5,error; 29. rts r5 2: jsr r5,getsym rts r5 1: tst r0 beq e11 / unknown jsr r5,error; 30. rts r5 / name e11: mov r3,r2 jsr r5,getsym cmp r0,$32. / ( bne 1f jsr r5,appl jsr r5,block; e10 rts r5 1: mov r2,r3 mov r0,-(sp) jsr r5,declimpl mov symtab(r3),r0 bic $!70,r0 cmp r0,$30 / class =| funct bne 1f jsr r5,appl mov $42.,r3 / just function name br 2f 1: clr r3 2: mov (sp)+,r0 mov r2,-(sp) mov blockp,r2 add $6,blockp mov r3,(r2) mov (sp)+,2(r2) clr 4(r2) rts r5 / number 3: mov blockp,r2 add $6,blockp mov r0,(r2) mov r3,2(r2) cmpb 2(r2),$5 / const->int bne 4f movb $1,2(r2) 4: mov r3,temp mov conu,4(r2) inc conu jsr r5,ptemp; 'c; temp; symbuf jsr r5,getsym rts r5 appl: clr functn bit $70,symtab(r2) / class bne 1f bis $30,symtab(r2) jsr r5,funimpl 1: mov r2,r3 jsr r5,declimpl mov symtab(r2),r0 bic $!70,r0 / class again cmp r0,$20 / array beq 1f cmp r0,$30 / funct beq 2f jsr r5,error; 33. bic $70,symtab(r2) br appl 1: mov $32.,r0 rts r5 2: mov $34.,r0 rts r5 block: mov blockp,r3 add $6,blockp mov r0,(r3)+ mov r2,(r3)+ mov r3,-(sp) jsr r5,*(r5)+ mov r2,*(sp) mov (sp)+,r2 sub $4,r2 rts r5 mp; 'c; temp; symbuf jsr r/ / / f33 -- do, etal .globl sdo .globl dobeg .globl doend .globl getlab .globl e2 .globl error .globl lvalue .globl rvalue .globl code .globl convrt .globl dou .globl dotabp .globl edotab .globl dotab sdo: jsr r5,getlab br 9f jsr r5,dobeg cmp r0,$40. bne 9f rts r5 7: tst (sp)+ 8: tst (sp)+ 9: jsr r5,error; 42. rts r5 dobeg: mov dotabp,r2 cmp r2,$edotab blo 1f jsr r5,error; 44. rts r5 1: mov dou,dotab(r2) inc dou mov r0,dotab+2(r2) add $4,dotabp jsr r5,e2 cmp r0,$38. / = bne 9b mov r2,-(sp) jsr r5,lvalue mov r3,-(sp) bic $!7,r3 cmp r3,$1 / integer bne 7b jsr r5,e2 cmp r0,$36. / , bne 7b jsr r5,rvalue mov (sp),r2 jsr r5,convrt mov (sp),r3 clrb r3 swab r3 jsr r5,code < gas%d\n goto; 2f\n\0>; .even r3 mov dotabp,r2 mov dotab-4(r2),r0 jsr r5,code ; .even r0 mov (sp)+,r3 mov (sp)+,r2 mov r0,-(sp) mov r3,-(sp) jsr r5,lvalue jsr r5,e2 mov r0,-(sp) jsr r5,rvalue mov 2(sp),r2 jsr r5,convrt cmp (sp)+,$36. / , bne 1f jsr r5,e2 mov r0,-(sp) jsr r5,rvalue mov 2(sp),r2 jsr r5,convrt mov (sp)+,r0 jsr r5,code < do2\0>; .even br 2f 1: jsr r5,code < do1\0>; .even 2: mov (sp)+,r3 clrb r3 swab r3 mov (sp)+,r2 jsr r5,code <%d; o%d\n2:\n\0>; .even r3 r2 rts r5 doend: tst r0 bne 1f jsr pc,gen rts r5 1: clr r2 1: cmp r2,dotabp bhis 1f add $4,r2 cmp r0,dotab-2(r2) bne 1b jsr pc,gen br doend 1: rts r5 gen: mov r0,-(sp) mov dotabp,r2 cmp r0,dotab-2(r2) beq 1f jsr r5,error; 43. 1: mov dotab-4(r2),r0 sub $4,dotabp jsr r5,code < goto; t%d\no%d:\n\0>; .even r0 r0 mov (sp)+,r0 rts pc 2\0>; .even br 2f 1: jsr r5,code < do1\0>; .even 2: mov (sp)+,r3 clrb r3 swab r3 mov (sp)+,r2 jsr r5,code <%d; o%d\n2:\n\0>; .even r3 r2 rts r5 doend: tst r0 bne 1f jsr pc,gen rts r5 1: clr r2 1: cmp r2,dotabp bhis 1f add $4,r2 cmp r0,dotab-2(r2) bne 1b jsr pc,gen br doend 1: rts r5 gen: mov r0,-(sp) mov dotabp,r2 cmp r0,dotab-2(r2) beq 1f jsr r5,error; 43. 1: mov dotab-4(r2),r0 sub $4,dotab/ / / f34 -- if statement .globl sif .globl e2 .globl error .globl rvalue .globl code .globl ifstmt .globl iserror .globl getsym .globl geti .globl genop .globl getlab .globl newline sif: jsr r5,e2 / expression jsr r5,iserror br 9f cmp r0,$34. / ) bne 9f jsr r5,rvalue mov $"if,r0 jsr r5,genop bic $!7,r3 cmp r3,$3 / logical bne 1f jsr r5,code <; 1f\n\0>; .even jsr r5,ifstmt jsr r5,code <1:\n\0>; .even rts r5 1: mov $3,-(sp) 1: jsr r5,getlab br 8f jsr r5,code <; .%d\0>; .even r0 dec (sp) beq 1f jsr r5,getsym cmp r0,$36. beq 1b 8: tst (sp)+ br 9f 1: tst (sp)+ jsr r5,newline jsr r5,getsym cmp r0,$40. bne 9f rts r5 9: jsr r5,error; 40. rts r5 : jsr r5,e2 / expression jsr r5,iserror br 9f cmp r0,$34. / ) bne 9f jsr r5,rvalue mov $"if,r0 jsr r5,genop bic $!7,r3 cmp r3,$3 / logical bne 1f jsr r5,code <; 1f\n\0>; .even jsr r5,ifstmt jsr r5,code <1:\n\0>; .even rts r5 1: mov $3,-(sp) 1: jsr r5,getlab br 8f jsr r5,code <; .%d\0>; .e/ / / f35 -- assignment statement .globl sasgn .globl sassi .globl error .globl e2 .globl lvalue .globl rvalue .globl code .globl convrt .globl geti .globl getsym .globl getlab .globl genop .globl newline .globl name sasgn: jsr r5,e2 cmp r0,$38. / = bne 9f mov r2,-(sp) jsr r5,e2 cmp r0,$40. / =| bne 8f tst *(sp) bne 1f / too hard for simple as jsr r5,rvalue mov (sp)+,r2 mov 2(r2),r2 mov r2,-(sp) mov symtab(r2),r2 jsr r5,convrt mov r2,r3 bis $7,r3 mov $"mv,r0 jsr r5,genop mov (sp)+,r3 jsr r5,name rts r5 1: mov r2,r3 mov (sp)+,r2 mov r3,-(sp) jsr r5,lvalue mov (sp)+,r2 mov r3,-(sp) jsr r5,rvalue 1: mov (sp)+,r2 jsr r5,convrt mov r2,r3 bis $7,r3 / type 'g' mov $"as,r0 jsr r5,genop jsr r5,newline rts r5 sassi: jsr r5,getlab br 9f mov r0,-(sp) cmpb (r1)+,$'t bne 8f cmpb (r1)+,$'o bne 8f jsr r5,e2 cmp r0,$40. / =| bne 8f jsr r5,lvalue mov (sp)+,r0 mov r3,-(sp) jsr r5,code < lval; .%d\n\0>; .even r0 mov $int2con,r3 br 1b 8: tst (sp)+ 9: jsr r5,error; 39. rts r5 ts r5 1: mov r2,r3 mov (sp)+,r2 mov r3,-(sp) jsr r5,lvalue mov (sp)+,r2 mov r3,-(sp) jsr r5,rvalue 1: mov (sp)+,r2 jsr r5,convrt mov r2,r3 bis $7,r3 / type 'g' mov $"as,r0 jsr r5,genop jsr r5,newline rts r5 sassi: jsr r5,getlab br 9f mov r0,-(sp) cmpb (r1)+,$'t bne 8f cmpb (r1)+,$'o bne 8f jsr r5,e2 cmp r0,$40. / =| bne 8f jsr r5,lvalue mov (sp)+,r0 mov r3,-(sp) jsr r5,code < lval; .%d\n\0>; .even r0 mov $int2con,r3 br 1b 8: tst (sp)+ 9: jsr r5/ / / f36 -- expression code generation .globl lvalue .globl rvalue .globl convrt .globl type .globl funcappl .globl name .globl error .globl lookup .globl code .globl iserror .globl genop .globl typ .globl newline .globl functn .globl size lvalue: jsr r5,iserror rts r5 tst (r2) bne 1f mov 2(r2),r3 jsr r5,code < lval>; .even br name 1: mov r2,-(sp) cmp (r2),$32. / array appl bne 1f jsr r5,aryappl dec r0 bne 2f / dim =| 1 tstb symtab(r3) blt 2f / p-bit, not simple mov $"al,r0 br simpary 2: jsr r5,code < alval\0>; .even arydope: jsr r5,pbit mov symtab+2(r3),r2 mov (r2)+,r0 asl r0 add r0,r2 mov (r2),r0 jsr r5,code <; d%d\0>; .even r0 br 2f 1: jsr r5,error; 54. mov (sp)+,r2 rts r5 simpary: mov r3,-(sp) mov symtab(r3),r3 bis $7,r3 jsr r5,genop mov (sp)+,r3 jsr r5,size jsr r5,code <; %d.\0>; .even r0 br 2f name: mov r2,-(sp) jsr r5,pbit 2: jsr r5,code <; \0>; .even bit $100,symtab(r3) / common beq 1f mov symtab+4(r3),r2 jsr r5,code <%n+\0>; .even r2 1: movb symtab(r3),r2 bic $!7,r2 cmp r2,$6 / undefined bne 1f jsr r5,error; 34. 1: movb symtab(r3),r2 bic $!70,r2 cmp r2,$30 / external bne 1f jsr r5,code <%n.\n\0>; .even r3 br 2f 1: jsr r5,code <%n_\n\0>; .even r3 2: mov symtab(r3),r3 mov (sp)+,r2 rts r5 rvalue: jsr r5,iserror rts r5 mov r2,-(sp) tst (r2) bne 1f mov 2(r2),r3 movb symtab+1(r3),r2 jsr r5,code < rval%d>; .even r2 mov (sp)+,r2 br name 1: cmp (r2),$32. bne 1f jsr r5,aryappl dec r0 bne 3f tstb symtab(r3) blt 3f mov $"ar,r0 br simpary 3: jsr r5,code < arval\0>; .even br arydope 1: cmp (r2),$34. / array appl bne 1f jsr r5,funcappl mov (sp)+,r2 mov 2(r2),r3 movb symtab+1(r3),r0 jsr r5,code <%d.\n\0>; .even r0 mov symtab(r3),r3 rts r5 1: cmp (r2),$2 bne 1f movb 3(r2),r3 mov 4(r2),r2 jsr r5,code < rval%d; c%d\n\0>; .even r3 r2 mov (sp)+,r2 mov 2(r2),r3 rts r5 1: cmp (r2),$24. / arith or relat bhi 1f mov 2(r2),r2 bne 3f mov (sp),r2 sub $10.,(r2) / - bin -> - unary mov 4(r2),r2 jsr r5,rvalue br 2f 3: jsr r5,rvalue mov (sp),r2 mov r3,-(sp) mov 4(r2),r2 jsr r5,type cmp *2(sp),$4 / ** bne 3f mov r3,r2 bic $!7,r2 cmp r2,$1 / ** integer bne 3f mov 2(sp),r2 sub $2,(r2) / pr -> pi mov 4(r2),r2 jsr r5,rvalue mov $intcon,r2 jsr r5,convrt mov (sp)+,r3 br 2f 3: mov (sp),r2 jsr pc,maxtyp mov (sp)+,r3 mov r2,-(sp) jsr r5,convrt mov 2(sp),r2 mov 4(r2),r2 jsr r5,rvalue mov (sp)+,r2 jsr r5,convrt mov r2,r3 br 2f 1: cmp (r2),$30. / and or not bhi 1f mov 2(r2),r2 beq 3f jsr r5,rvalue mov $logcon,r2 jsr r5,convrt 3: mov (sp),r2 mov 4(r2),r2 jsr r5,rvalue mov $logcon,r2 jsr r5,convrt 2: mov (sp)+,r2 mov (r2),r0 cmp r0,$4 bhis 2f add $10.,(r2) / back to binary tst r0 beq 2f sub $8,(r2) / back to pr 2: mov optab(r0),r0 jsr r5,genop jsr r5,newline cmp (r2),$14. / relat blo 2f mov $logcon,r3 2: rts r5 1: jsr r5,error; 54. mov (sp)+,r2 rts r5 pbit: tstb symtab(r3) bge 1f jsr r5,code 1: rts r5 funcappl: mov r2,-(sp) mov functn,r3 jsr r5,code < stsp; ft+%d.\n\0>; .even r3 mov r3,-(sp) add $2,r3 mov r3,functn clr -(sp) / nargs 1: mov 4(r2),r2 beq 2f inc (sp) cmp (r2),$36. / , bne 1f mov r2,-(sp) mov 2(r2),r2 mov 6(sp),r3 jsr r5,fapp1 mov (sp)+,r2 br 1b 1: mov 4(sp),r3 jsr r5,fapp1 2: mov (sp)+,r0 / nargs mov (sp)+,r2 mov (sp)+,r3 mov 2(r3),r3 jsr r5,code < call\0>; .even jsr r5,pbit jsr r5,code <; %n.; ft+%d.; %d.; \0>; .even r3 r2 r0 cmp functn,functm ble 1f mov functn,functm 1: mov r2,functn rts r5 fapp1: mov 2(r3),r3 / fetch out function name mov symtab+2(r3),r3 / arg conversion bne 2f tst (r2) beq 1f cmp (r2),$32. beq 4f cmp (r2),$42. / lv if funct or name or arry app beq 1f cmp (r2),$2 / lv if const bne 2f mov 4(r2),r3 jsr r5,code < lval; c%d\n\0> r3 br 3f 2: mov r3,-(sp) jsr r5,rvalue mov (sp)+,r2 beq 2f jsr r5,convrt 2: mov functn,r3 jsr r5,code < stsp; ft+%d.\n\0>; .even r3 add $2,functn rts r5 1: clr (r2) / turn func/array names into lvs 4: jsr r5,lvalue 3: mov functn,r3 jsr r5,code < stst; ft+%d.\n\0>; .even r3 add $2,functn rts r5 aryappl: mov r2,-(sp) clr -(sp) / arg count 2: inc (sp) mov 4(r2),r2 cmp (r2),$36. / , bne 2f mov r2,-(sp) mov 2(r2),r2 jsr r5,rvalue mov $intcon,r2 jsr r5,convrt mov (sp)+,r2 br 2b 2: jsr r5,rvalue mov $intcon,r2 jsr r5,convrt mov (sp)+,r0 mov (sp)+,r2 mov 2(r2),r3 cmp r0,*symtab+2(r3) beq 1f jsr r5,error; 53. / dimension mismatch 1: rts r5 / converts stack from type in r3 to type in r2 convrt: mov r2,-(sp) mov r3,-(sp) bic $![377\<8+7],r2 bic $![377\<8+7],r3 cmp r2,r3 beq 1f jsr r5,code < \0>; .even jsr pc,2f mov r2,r3 jsr pc,2f jsr r5,code <\n\0>; .even 1: mov (sp),r2 bic $!7,r2 cmp r2,$6 beq 3f mov 2(sp),r2 bic $!7,r2 cmp r2,$6 bne 1f 3: jsr r5,error; 34. 1: mov (sp)+,r3 mov (sp)+,r2 rts r5 2: mov r2,-(sp) mov r3,r2 clrb r3 swab r3 bic $!7,r2 movb typ(r2),r2 jsr r5,code <%c%d\0>; .even r2 r3 mov (sp)+,r2  rts pc type: cmp (r2),$32. beq 2f cmp (r2),$34. beq 2f tst (r2) bne 1f 2: mov 2(r2),r3 mov symtab(r3),r3 rts r5 1: cmp (r2),$2 bne 1f mov 2(r2),r3 rts r5 1: cmp (r2),$14. blo 1f mov $logcon,r3 rts r5 1: mov r2,-(sp) mov 2(r2),r2 bne 1f mov (sp),r2 mov 4(r2),r2 jsr r5,type br 2f 1: jsr r5,type mov (sp),r2 mov r3,-(sp) mov 4(r2),r2 jsr r5,type mov (sp)+,r2 jsr pc,maxtyp mov r2,r3 2: mov (sp)+,r2 rts r5 maxtyp: mov r2,r0 cmp r2,r3 bhis 2f mov r3,r2 2: clrb r2 bic $!7,r0 bic $!7,r3 cmp r0,r3 bhis 2f mov r3,r0 2: bis r0,r2 rts pc optab: cmp (r2),$14. blo 1f mov $logcon,r3 rts r5 1: mov r2,-(sp) mov 2(r2),r2 bne 1f mov (sp),r2 mov 4(r2),r2 jsr r5,type br 2f 1: jsr r5,type mov (sp),r2 mov r3,-(sp) mov 4(r2),r2 jsr r5,type mov (sp)+,r2 jsr pc,maxtyp mov r2,r3 2: mov (sp)+,r2 rts r5 maxtyp: mov r2,r0 cmp r2,r3 bhis 2f mov r3,r2 2: clrb r2 bic $!7,/ / / f37 -- goto statements of all kinds .globl sgoto .globl intexp .globl e2 .globl code .globl getsym .globl error .globl getlab .globl rvalue .globl convrt .globl chrtab sgoto: movb (r1),r0 cmpb chrtab(r0),$4 / test digit bne 1f / not constant jsr r5,getlab br 8f jsr r5,code < goto; .%d\n\0>; .even r0 br 9f 1: cmpb (r1),$'( beq 1f jsr r5,intexp cmp r0,$36. / , beq 2f jsr r5,code < agoto\n\0>; .even br 9f 2: jsr r5,code < cagoto\n\0>; .even cmpb (r1)+,$'( bne 8f / syntax jsr pc,stmlist br 9f 1: mov r1,r4 1: movb (r1)+,r0 beq 8f cmp r0,$') bne 1b cmpb (r1)+,$', bne 8f jsr r5,intexp mov r1,-(sp) jsr r5,code < cgoto\n\0>; .even mov r4,r1 tstb (r1)+ jsr pc,stmlist mov (sp)+,r1 9: tstb (r1) beq 1f 8: jsr r5,error; 35. 1: rts r5 stmlist: jsr r5,getlab br 9f jsr r5,code < .%d\n\0>; .even r0 movb (r1)+,r0 cmp r0,$', beq stmlist cmp r0,$') bne 8f jsr r5,code < 0\n\0>; .even rts pc 8: jsr r5,error; 35. 9: rts pc intexp: jsr r5,e2 mov r0,-(sp) jsr r5,rvalue mov $intcon,r2 jsr r5,convrt mov (sp)+,r0 rts r5 ) bne 1b cmpb (r1)+,$', bne 8f jsr r5,intexp mov r1,-(sp) jsr r5,code < cgoto\n\0>; .even mov r4,r1 tstb (r1)+ jsr pc,stmlist mov (sp)+,r1 9: tstb (r1) beq 1f 8: jsr r5,error; 35. 1: rts r5 stmlist: jsr r5,getlab br 9f jsr r5,code < .%d\n\0>; .even r0 movb (r1)+,r0 cmp r0,$', beq stmlist cmp r0,$') bne 8f jsr r5,code < 0\n\0>; .even rts pc 8: jsr r5,error; 35. 9: rts pc intexp: jsr r5,e2 mov r/ / / f38 -- wierdo statements .globl sstop .globl scall .globl spaus .globl sretu .globl scont .globl iserror .globl ptemp .globl code .globl geti .globl getsym .globl error .globl declimpl .globl e11 .globl funcappl sstop: clr r0 tstb (r1) beq 1f jsr r5,getsym cmp r0,$2. / const bne 7f cmp r3,$intcon bne 7f jsr r5,geti 1: jsr r5,code < stop; %d\n\0>; .even r0 br 8f spaus: jsr r5,getsym cmp r0,$2 bne 7f cmp r3,$intcon bne 7f jsr r5,geti jsr r5,code < paus; %d\n\0>; .even r0 br 8f sretu: tst progt bne 1f jsr r5,error; 37. / return in main br sstop 1: jsr r5,code < retrn\n\0>; .even 8: scont: tstb (r1) bne 7f rts r5 7: jsr r5,error; 38. rts r5 iserror: cmp errp,$errb bne 1f tst (r5)+ 1: rts r5 scall: jsr r5,getsym tst r0 bne 7b bit $70,symtab(r3) bne 1f bis $30,symtab(r3) 1: jsr r5,declimpl jsr r5,e11 cmp r0,$40. bne 7b cmp (r2),$34. beq 1f cmp (r2),$42. bne 7b 1: jsr r5,funcappl jsr r5,code <0\n\0>; .even br 8b us; %d\n\0>; .even r0/ / / f39 -- i/o statements .globl sread .globl swrit .globl sprin .globl sback .globl srewi .globl sendf .globl getsym .globl error .globl geticon .globl e2 .globl lvalue .globl rvalue .globl iserror .globl convrt .globl code .globl chrtab .globl blocks .globl blockp .globl doend .globl genop .globl levzer .globl dobeg .globl intexp .globl ptemp .globl blocks .globl blockp .globl intexp .globl newline .globl nelem sprin: mov $8.,-(sp) jsr r5,getfmt br 9f cmp r0,$36. / , beq 1f cmp r0,$40. / =| bne 8f clrb (r1) 1: mov $34.,r0 / simulate ) br 2f sread: mov $2,-(sp) br 1f swrit: clr -(sp) 1: cmpb (r1)+,$'( bne 8f jsr r5,intexp mov $blocks,blockp cmp r0,$34. / ), implies unformatted beq 2f cmp r0,$36. / , bne 8f jsr r5,getfmt br 9f add $4,(sp) cmp r0,$34. / ) bne 8f 2: mov (sp),r0 mov iotype(r0),r0 jsr r5,code < %s\n\0>; .even r0 1: tstb (r1) beq 9f 1: jsr r5,list cmp r0,$40. / |= beq 9f 8: jsr r5,error; 41. 9: jsr r5,code < endio\n\0>; .even tst (sp)+ rts r5 iotype: 1f 2f 3f 4f 5f 1: 2: 3: 4: 5: .even getfmt: movb (r1),r0 cmpb chrtab(r0),$4 / digit beq 1f jsr r5,e2 jsr r5,iserror rts r5 mov r0,-(sp) jsr r5,lvalue mov $blocks,blockp br 8f 1: jsr r5,geticon br 8f mov r0,temp jsr r5,ptemp; 'i; temp; line / register use of format jsr r5,code < lval; .%d\n\0>; .even r0 jsr r5,getsym mov r0,-(sp) 8: mov (sp)+,r0 tst (r5)+ rts r5 list: jsr r5,lstitm cmp r0,$36. / , beq list rts r5 lstitm: mov $blocks,blockp cmpb (r1),$'( / test for sublist beq 1f jsr r5,e2 jsr r5,iserror rts r5 mov r0,-(sp) clr -(sp) tst (r2) bne 2f / test for name mov 2(r2),r3 mov symtab(r3),r0 bic $!70,r0 cmp r0,$20 / test for short list bne 2f mov pc,(sp) mov symtab+2(r3),r3 mov (r3)+,-(sp) asl (sp) add (sp)+,r3 mov (r3),r3 jsr r5,code < slist1; d%d\n2:\0>; .even r3 2: jsr r5,lvalue tst (sp) beq 3f jsr r5,code < slist3\n\0>; .even 3: mov $"io,r0 jsr r5,genop tst (sp)+ beq 2f jsr r5,code <\n slist2; 2b\0>; .even 2: jsr r5,newline mov (sp)+,r0 rts r5 1: inc r1 jsr r5,levzer; '= br 1f / yes, implied do jsr r5,list jsr r5,chkel jsr r5,getsym rts r5 1: cmp r1,r0 bhis 8f cmpb -(r0),$', / look backwards bne 1b mov r0,-(sp) mov r1,-(sp) movb $'),(r0) / fake!! mov r0,r1 inc r1 clr r0 jsr r5,dobeg / get do jsr r5,chkel mov (sp)+,r0 mov r1,-(sp) mov r0,r1 jsr r5,list jsr r5,chkel clr r0 jsr r5,doend mov (sp)+,r1 movb $',,*(sp)+ / unfake!! jsr r5,getsym rts r5 chkel: cmp r0,$34. / ) beq 1f 8: jsr r5,error; 41. 1: rts r5 sback: mov $bksp,r2 br 1f srewi: mov $rewi,r2 br 1f sendf: mov $enfl,r2 1: mov r2,-(sp) jsr r5,intexp mov (sp),r2 jsr r5,code < %s\n\0>; .even r2 cmp r0,$40. / =| beq 9f 8: jsr r5,error; 41. 9: tst (sp)+ rts r5 bksp: rewi: enfl: kel mov (sp)+,r0 mov r1,-(sp) mov r0,r1 jsr r5,list jsr r5,chkel clr r0 jsr r5,doend mov (sp)+,r1 movb $',,*(/ / / f41 -- everything else .globl pass4 .globl signon .globl flush .globl dope .globl formts .globl globls .globl constn .globl fopen .globl bsss .globl tfil2 pass4: setd jsr r5,signon; 4 mov ibuf,r0 sys close jsr r5,flush; obuf jsr r5,flush; tbuf jsr r5,dope jsr r5,formts jsr r5,constn jsr r5,bsss jsr r5,globls / uses r4 from bsss jsr r5,flush; obuf sys unlink; tfil2 clr r0 tst nerror beq 1f sys seek; 0; 2 mov $1,r0 / syntax errors 1: sys exit 5,doend mov (sp)+,r1 movb $',,*(/ / / 42 -- definition .globl bsss .globl code .globl size .globl declimpl .globl cdata .globl dodata .globl dattab bsss: jsr r5,cdata cmp progt,$6 / test block common bne 1f rts r5 1: jsr r5,code <.bss\n\0>; .even mov functm,r3 beq 1f jsr r5,code ; .even r3 1: cmp r4,$dattab / any data? beq 1f jsr r5,code <.data\n\0>; .even 1: jsr r5,code ; .even clr r3 1: cmp r3,symtp bhis pass2 bit $70,symtab(r3) / test classed bne 2f jsr r5,declimpl 2: mov symtab(r3),r0 mov symtab+6(r3),r2 bic $!70,r0 / class cmp r0,$10 / simple beq 1f cmp r0,$20 / array beq 1f cmp r0,$30 / extrn bne 2f bit $200,symtab(r3) / param beq 2f jsr r5,code <%n. = %d.\n\0>; .even r3 r2 2: cmp r0,$40 / common block bne 2f mov symtab+6(r3),r2 / size beq 2f jsr r5,code <.comm %n,%d.\n\0>; .even r3 r2 2: add $8,r3 br 1b 1: bit $300,symtab(r3) beq 1f jsr r5,code <%n_ = %d.\n\0>; .even r3 r2 br 2b 1: tst r2 bne 1f jsr r5,size mov nxtaloc,r2 mov r2,symtab+6(r3) add r0,nxtaloc 1: jsr r5,code <%n_ = base+%d.\n\0>; .even r3 r2 br 2b pass2: jsr r5,dodata rts r5 n bne 2f bit $200,symtab(r3) / param beq 2f jsr r5,code <%n. = %d.\n\0>; .even r3 r2 2: cmp r0,$40 / common block bne 2f mov symtab+6(r3),r2 / size beq 2f jsr r5,code <.comm %n,%d.\n\0>; .even r3 r2 2: add $8,r3 br 1b 1: bit $300,symtab(r3) beq 1f jsr r5,code <%n_ = %d.\n\0>; .even r3 r2 br 2b 1: tst r2 bne 1f jsr r5,size mov n/ / / f43 -- output globals and bdata bss's .globl globls .globl code .globl dattab .globl onedata .globl error .globl perror globls: mov progt,r0 jmp *1f(r0) 1: 1f 2f 3f 4f 1: jsr r5,code <.globl main\n\0>; .even rts r5 2: 3: jsr r5,code <.globl %n.\n\0>; .even 8 rts r5 4: 1: clr r3 1: cmp r3,symtp blo 2f rts r5 2: mov symtab(r3),r0 bic $!270,r0 cmp r0,$40 / common block bne 2f mov symtab+6(r3),r2 beq 2f mov $dattab,r1 3: cmp r1,r4 bhis 3f cmp (r1),r3 beq 4f add $8.,r1 br 3b 3: jsr r5,code <.bss\n.globl %n\n%n: .=.+%d.\n.text\n\0>; .even r3 r3 r2 br 2f 4: jsr r5,code <.data\n.globl %n\n%n:\n\0>; .even r3 r3 mov r2,-(sp) mov r3,-(sp) mov r1,r3 jsr r5,onedata mov (sp)+,r3 mov (sp)+,r2 sub r1,r2 bge 9f jsr r5,error; 22. / data overrun jsr r5,perror 9: jsr r5,code <.=.+%d.\n.text\n\0>; .even r2 2: add $8,r3 br 1b 40 / common block bne 2f mov symtab+6(r3),r2 beq 2f mov $dattab,r1 3: cmp r1,r4 bhis 3f cmp (r1),r3 beq 4f add $8.,r1/ / / f44 -- formats .globl formts .globl strout .globl setln .globl getln .globl code .globl error .globl perror .globl putc .globl xbuf formts: cmp progt,$2 blt 1f cmp progt,$4 bgt 1f jsr r5,code \n\0>; .even 8 1: jsr r5,setln mov $2,r3 clr xbuf+518. / pick up zero efn formats 1: jsr r5,getln br 1f cmp r0,$'s beq 2f cmp r0,$'f bne 1b mov efno,r0 jsr r5,code <.%d: <\0>; .even r0 mov $line+6,r1 jsr r5,strout mov efno,r0 neg r0 br 3f 2: mov efno,r0 3: clr r2 2: cmp r2,r3 bhis 2f cmp r0,xbuf+518.(r2) beq 3f neg r0 cmp r0,xbuf+518.(r2) beq 3f add $2,r2 neg r0 br 2b 3: jsr r5,error; 51. jsr r5,perror 2: mov r0,xbuf+518.(r3) add $2,r3 br 1b 1: jsr r5,code < .even\n>; .even jsr r5,setln 1: jsr r5,getln br 1f cmp r0,$'r beq 2f cmp r0,$'i bne 1b mov efno,r0 neg r0 br 3f 2: mov efno,r0 3: mov $2,r2 / not zero 2: cmp r2,r3 bhis 2f cmp r0,xbuf+518.(r2) beq 1b add $2,r2 br 2b 2: jsr r5,error; 52. jsr r5,perror br 1b 1: rts r5 strout: movb (r1)+,r0 beq 3f cmp r0,$'> beq 4f cmp r0,$'\\ bne 5f 4: mov r0,-(sp) mov $'\\,r0 jsr r5,putc; obuf mov (sp)+,r0 5: jsr r5,putc; obuf br strout 3: jsr r5,code <\\0\>\n\0>; .even rts r5 < .even\n>; .even jsr r5,setln 1: jsr r5,getln br 1f cmp r0,$'r beq 2f cmp r0,$'i bne 1b mov efno,r0 neg r0 br 3f 2: mov efno,r0 3: mov $2,r2 / not zero 2: cmp r2,r3 bhis 2f cmp r0,xbuf+518.(r2) beq 1b add $2,r2 br 2b 2: jsr r5,error; 52. jsr r5,perror br 1b 1: rts r5 / / / f45 -- constant pool .globl constn .globl evalcon .globl error .globl perror .globl code .globl getcon .globl setln .globl getln .globl xbuf .globl symbuf .globl negflg constn: jsr r5,setln mov $xbuf+518.,r3 / pool max pointer mov $ibuf+518.,r4 / pool pointer pointer 1: jsr r5,getln br 1f cmp r0,$'c bne 1b jsr r5,packcon mov r2,-(r4) / put p ptr in p p ptr cmp r3,r4 blo 1b jsr r5,error; 99. jsr r5,perror 1: mov $xbuf+518.,r2 1: cmp r2,r3 bhis 1f mov $ibuf+518.,r1 2: cmp r1,r4 blo 2f cmp -(r1),r2 bne 2b mov r1,r0 sub $ibuf+516.,r0 asr r0 neg r0 jsr r5,code ; .even r0 br 2b 2: mov (r2)+,r0 jsr r5,code < %o\n\0>; .even r0 br 1b 1: rts r5 packcon: mov $line,r1 jsr r5,evalcon mov r1,-(sp) mov r3,-(sp) sub r2,(sp) asr (sp) mov r2,-(sp) mov $xbuf+518.,r2 1: mov (sp),r3 mov r2,r1 tst (r2)+ mov 2(sp),r0 2: cmp (r1)+,(r3)+ bne 1b dec r0 bgt 2b tst -(r2) mov (sp)+,r3 asl (sp) add r2,(sp) cmp (sp),r3 blos 1f mov (sp),r3 / eureka 1: tst (sp)+ mov (sp)+,r1 rts r5 evalcon: cmpb efno,$5 bne 2f movb efno+1,r0 mov r3,r2 br 1f 2: jsr r5,getcon tst negflg beq 2f negf fr0 negf fr1 2: mov r3,r2 mov efno,r0 mov r0,r1 clrb r0 swab r0 bic $!7,r1 cmpb r1,$realcon beq 3f cmpb r1,$cplxcon beq 2f setl movfi r0,symbuf+1 seti mov $symbuf+5,r1 sub r0,r1 br 1f 2: mov $symbuf+1,r1 movf fr1,symbuf+1 cmp r0,$8 beq 2f movf fr0,symbuf+9. br 1f 2: movf fr0,symbuf+5 br 1f 3: movf fr0,symbuf+1 mov $symbuf+1,r1 1: movb (r1)+,(r3)+ dec r0 bgt 1b bit $1,r3 beq 1f clrb (r3)+ 1: rts r5 ovb efno+1,r0 mov r3,r2 br 1f 2: jsr r5,getcon tst negflg beq 2f negf fr0 negf fr1 2: mov r3,r2 mov efno,r0 mov r0,r1 clrb r0 swab r0 bic $!7,r1 cmpb r1,$realcon beq 3f cmpb r1,$cplxcon beq 2f setl movfi r0,symbuf+1 seti mov $symbuf+5,r1 sub r0,r1 br 1f 2: mov $symbuf+1,r1 movf fr1,symbuf+1 cmp r0,$8 beq 2f movf fr0,symbuf+9. br 1f 2: movf fr0,symbuf+5 br 1f 3: movf fr0,symbuf+1 mov $symbuf+1,r1 1: movb (r1)+/ / / f46 -- constant evaluation .globl getcon .globl dope .globl code getcon: mov r0,-(sp) mov r2,-(sp) clr r2 / dec . counter clrf fr0 movif $10.,fr1 clr -(sp) / - flag cmpb (r1)+,$'+ beq 1f cmpb -(r1),$'- bne 1f inc r1 inc (sp) 1: movb (r1)+,r0 sub $'0,r0 cmp r0,$9 blos 2f cmp r0,$'.-'0 bne 1f dec r2 br 1b 2: tst r2 beq 2f dec r2 2: mulf fr1,fr0 movif r0,fr2 addf fr2,fr0 br 1b 1: tst r2 bne 1f dec r2 1: cmp r0,$'e-'0 beq 2f cmp r0,$'d-'0 bne 1f 2: mov r3,-(sp) clr r3 clr -(sp) cmpb (r1),$'- bne 3f inc r1 inc (sp) br 2f 3: cmpb (r1),$'+ bne 2f inc r1 2: movb (r1)+,r0 sub $'0,r0 cmp r0,$9 bhi 2f mpy $10.,r3 add r0,r3 br 2b 2: tst (sp)+ beq 2f neg r3 2: add r3,r2 mov (sp)+,r3 1: movf fr1,fr2 add $1,r2 beq 1f blt 2f clr -(sp) br 3f 2: mov pc,-(sp) neg r2 3: sub $1,r2 ble 2f mulf fr1,fr2 cmpf $75232,fr2 / about 1e35 cfcc bgt 3b 2: tst (sp) bne 2f mulf fr2,fr0 br 5f 2: divf fr2,fr0 5: tst r2 ble 2f movf $40200,fr2 br 3b 2: tst (sp)+ 1: tst (sp)+ beq 1f negf fr0 1: cmpb -(r1),$', bne 1f movf fr0,-(sp) inc r1 jsr r5,getcon movf (sp)+,fr1 / a,b -> r1,r0 1: mov (sp)+,r2 mov (sp)+,r0 rts r5 dope: cmp progt,$6 / test "block data" bne 1f rts r5 1: clr r3 1: cmp r3,symtp bhis 1f mov symtab(r3),r0 bic $!70,r0 cmp r0,$20 bne 2f mov symtab+2(r3),r0 beq 2f mov (r0)+,r1 mov r1,r2 asl r2 add r0,r2 mov (r2),r0 jsr r5,code ; .even r0 r1 3: dec r1 blt 3f mov -(r2),r0 bge 4f jsr r5,code <..; \0>; .even br 3b 4: jsr r5,code <%d.; \0>; .even r0 br 3b 3: mov symtab(r3),r2 clrb r2 swab r2 jsr r5,code <%d.\n\0>; .even r2 2: add $8,r3 br 1b 1: rts r5 : cmp progt,$6 / test "block data" bne 1f rts r5 1: clr r3 1: cmp r3,symtp bhis 1f mov symtab(r3),r0 bic $!70,r0 cmp r0,$20 bne 2f mov symtab+2(r3),r0 beq 2f mov (r0)+,r1 mov r1,r2 asl r2 add r0,r2 mov (r2),r0 jsr r5,code ; .even r0 r1 3: dec r1 blt 3f mov -(r2),r0 bge 4f jsr r5,code/ / / f47 -- analysis of data statements .globl cdata .globl dodata .globl onedata .globl compare .globl code .globl getcon .globl error .globl getsym .globl consub .globl size .globl geti .globl setln .globl getln .globl declimpl .globl evalcon .globl dattab .globl contab .globl efno .globl perror .globl qsort .globl negflg .globl repfact .globl geti .globl holround cdata: mov r5,-(sp) jsr r5,setln mov $dattab,r4 mov $contab,r5 dloop: jsr r5,getln br 2f br 1f 2: mov r4,-(sp) mov $dattab,r1 mov r4,r2 mov $8.,r3 jsr pc,qsort mov (sp)+,r4 mov (sp)+,r5 rts r5 1: cmp r0,$'d bne dloop mov $line+4,r1 / loop per specification-set 1: clr repfact mov r1,r2 2: jsr r5,getsym cmp r0,$40. / =| bne 3f 8: jmp 8f 9: jmp 9f 3: cmp r0,$6 / / bne 2b mov r1,-(sp) mov r2,r1 mov (sp)+,r2 / loop per specification 2: cmp r4,r5 blo 3f jmp 7f 3: jsr r5,getsym tst r0 bne 8b bit $70,symtab(r3) / test classed bne 3f jsr r5,declimpl 3: mov symtab(r3),r0 mov r0,holquo / temp storage incb holquo+1 / round size bicb $1,holquo+1 bit $200,r0 / test parameter bne 9b bic $!70,r0 cmp r0,$10 / simple beq 3f cmp r0,$20 / array bne 9b 3: bit $100,symtab(r3) / test common beq 3f cmp progt,$6 / test block data bne 9b mov symtab+4(r3),(r4)+ / common block br 4f 3: cmp progt,$6 / test block data beq 9b clr (r4)+ tst symtab+6(r3) / test allocated bne 4f mov nxtaloc,symtab+6(r3) jsr r5,size add r0,nxtaloc 4: clr (r4) / offset slot cmpb (r1),$'( / test subscript bne 3f inc r1 jsr r5,consub bic $70,holquo bis $10,holquo / array -> scalar mov r0,(r4) 3: movb symtab+1(r3),r0 / width of item inc r0 bic $1,r0 mov r0,holround add symtab+6(r3),(r4)+ tst repfact beq 3f dec repfact movb efno+1,r3 mov r3,(r4)+ mov r5,(r4)+ br 4f 3: mov r1,-(sp) mov r2,r1 mov (sp)+,r2 5: jsr r5,getsym cmp r0,$12. / + beq 5b cmp r0,$2 / constant beq 3f cmp r0,$10. / - bne 8f inc negflg jsr r5,getsym cmp r0,$2 / constant bne 8f 3: cmpb (r1)+,$'* bne 3f cmp r3,$intcon bne 8f jsr r5,geti dec r0 bmi 8f mov r0,repfact br 5b 3: dec r1 mov r1,-(sp) mov r2,-(sp) mov r3,efno clrb r3 swab r3 mov r3,(r4)+ sub r3,r5 mov r5,(r4)+ / ptr to const mov r5,r3 mov $symbuf,r1 jsr r5,evalcon clr negflg mov (sp)+,r1 mov (sp)+,r2 / note r1 <=> r2 4: cmpb efno+1,holquo+1 / compare sizes blt 9f / constant too small beq 3f bicb $!77,holquo cmp holquo,$int2con+10 / simple int*2? bne 4f sub $2,-4(r4) / reduce const length cmpb efno,$5 beq 3f / hollerith, OK add $2,-2(r4) / get least sig. br 3f 4: bit $20,holquo / test array beq 9f cmpb efno,$5 / test hollerith bne 9f 3: cmpb (r1),$'/ beq 3f cmpb (r1)+,$', bne 8f tst repfact bne 4f cmpb (r2)+,$', bne 8f 4: jmp 2b 3: cmpb (r2)+,$'/ bne 8f tstb (r2) beq 1f cmpb (r2),$', bne 3f inc r2 3: mov r2,r1 tst repfact bne 8f jmp 1b 7: jsr r5,error; 28. / data table overflow br 2f 8: jsr r5,error; 21. / data syntax error br 2f 9: jsr r5,error; 22. / data semantic error 2: mov $dattab,r4 / reset ptrs mov $contab,r5 jsr r5,perror 1: jmp dloop dodata: cmp progt,$6 beq 1f / block data mov $dattab,r3 cmp r3,r4 bne 2f / is data mov nxtaloc,r0 jsr r5,code <.=.+%d.\n.text\n\0>; .even r0 rts r5 2: jsr r5,onedata sub nxtaloc,r1 neg r1 blt 9b jsr r5,code <.=.+%d.\n.text\n\0>; .even r1 1: rts r5 onedata: clr r1 2: mov 2(r3),r0 sub r1,r0 bmi 9f beq 3f jsr r5,code <.=.+%d.\n\0>; .even r0 add r0,r1 3: mov 4(r3),r0 add r0,r1 asr r0 mov r0,-(sp) mov 6(r3),r2 3: mov (r2)+,r0 jsr r5,code <%o\n\0>; .even r0 dec (sp) bne 3b tst (sp)+ add $8.,r3 cmp r3,r4 bhis 1f cmp (r3),-8(r3) / any more in this block beq 2b 1: rts r5 9: clr line jsr r5,error; 32. / overlapping data init jsr r5,perror rts r5 / comparison routine for qsort compare: cmp (r0),(r4) bne 1f cmp 2(r0),2(r4) 1: rts pc 1 2: mov 2(r3),r0 sub r1,r0 bmi 9f beq 3f jsr r5,code <.=.+%d.\n\0>; .even r0 add r0,r1 3: mov 4(r3),r0 add r0,r1 asr r0 mov r0,-(sp) mov/ / / io1 -- I/O operators .globl rerr .globl endio .globl rio4 .globl rio8 .globl iio1 .globl iio2 .globl iio4 .globl lio2 .globl lio1 .globl cio8 .globl cio16 .globl ecvt .globl fcvt .globl _ndigit endio: mov (sp)+,r5 rts r5 cio8: tst slcnt bne 2f inc slcnt tst -(r4) br rio4 2: clr slcnt mov ilval,-(sp) add $4,(sp) br rio4 cio16: tst slcnt bne 2f inc slcnt tst -(r4) br rio8 2: clr slcnt mov ilval,-(sp) add $8,(sp) br rio8 rio8: mov $8.\<8+'r,r0 br 1f rio4: mov $4\<8+'r,r0 br 1f iio4: mov $4\<8+'i,r0 br 1f iio2: mov $2\<8+'i,r0 br 1f lio2: mov $2\<8+'l,r0 br 1f iio1: mov $1\<8+'i,r0 br 1f lio1: mov $1\<8+'l,r0 1: mov r0,itype mov (sp)+,ilval mov (sp)+,r5 tst (r5)+ rts r5 r5 rts r5 cio8: tst slcnt bne 2f inc slcnt tst -(r4) br rio4 2: clr slcnt mov ilval,-(sp) add $4,(sp) br rio4 cio16: tst slcnt bne 2f inc slcnt tst -(r4) br rio8 2: clr slcnt mov ilval,-(sp) add $8,(sp) br rio8 rio8: mov $8.\<8+'r,r0 br 1f rio4: mov $4\<8+'r,r0 / / / io2 -- format cracker .globl iowf .globl iowp .globl iorf iowp: mov (sp)+,formp mov $6,r1 br 1f iowf: mov (sp)+,formp tst (sp)+ mov (sp)+,r1 1: jsr r5,setio; 2 / write clr rdflg br 1f iorf: mov (sp)+,formp tst (sp)+ mov (sp)+,r1 jsr r5,setio; 1 / read mov pc,rdflg 1: clr binflg clr slcnt clr itmfnd clr scale clr itmflg mov $pbuf,ppar mov $-1,llpcnt jsr r5,fmtchr mov formp,llp cmp r0,$'( beq crack jsr r5,rerr; 106. sys exit crack: clr ngflg mov $1,rep item: jsr r5,fmtchr cmp $' ,r0 beq item cmp $'\t,r0 beq item jsr r5,switch; mswitch jsr r5,rerr; 105. sys exit mswitch: 'a; afmt 'f; ffmt 'e; efmt 'g; gfmt 'd; dfmt 'i; ifmt 'l; lfmt 'h; hfmt 'x; xfmt 'p; scal '-; minus '0; numb '1; numb '2; numb '3; numb '4; numb '5; numb '6; numb '7; numb '8; numb '9; numb ',; crack '/; slash '(; lpar '); rpar '"; quote ' ; item 0; 0 minus: jsr r5,gnum neg r0 br 1f numb: dec formp jsr r5,gnum 1: mov r0,rep br item scal: mov rep,scale br crack elist: tst _nocr beq 1f tst rdflg bne 1f jsr r5,eorec1 br 2f 1: jsr r5,eorec 2: jmp *(r4)+ slash: jsr r5,eorec br crack rpar: mov ppar,r0 cmp r0,$pbuf / see if outer parens blos 2f dec -2(r0) ble 1f / no repeats left mov -4(r0),formp / reset scan br crack 1: sub $4,ppar br crack / pop parens 2: jsr r5,getitm br elist tst itmfnd bne 1f jsr r5,rerr; 107. sys exit 1: jsr r5,eorec inc itmflg mov llpcnt,r1 bpl 1f mov llp,formp jmp crack 1: mov llp,r2 mov r2,formp mov ppar,r0 mov r2,(r0)+ mov r1,(r0)+ mov r0,ppar jbr crack1 lpar: mov ppar,r0 cmp r0,$pbuf+10 blo 1f jsr r5,rerr; 108. sys exit 1: mov formp,(r0)+ mov rep,(r0)+ mov r0,ppar cmp r0,$pbuf+4 bhi 1f mov formp,llp mov rep,llpcnt 1: jmp crack quote: inc ngflg mov $44,-(sp) br 3f hfmt: inc ngflg mov $40,-(sp) br 3f xfmt: inc ngflg mov $34,-(sp) br 3f afmt: mov $30,-(sp) br 1f ifmt: clr -(sp) br 1f lfmt: mov $4,-(sp) 1: jsr r5,gnum mov r0,width br 2f ffmt: mov $10,-(sp) br 1f dfmt: mov $14,-(sp) br 1f gfmt: mov $20,-(sp) br 1f efmt: mov $24,-(sp) 1: jsr r5,gnum mov r0,width 4: jsr r5,fmtchr cmp r0,$' / beq 4b cmp r0,$'. bne err1 jsr r5,gnum mov r0,ndig 2: inc itmfnd 3: add $cvsw,(sp) tst rdflg beq 1f add $2,(sp) 1: mov *(sp)+,-(sp) 1: tst ngflg bne 2f jsr r5,getitm br 1f 2: clr gflg jsr r5,*(sp) dec rep bgt 1b tst (sp)+ br crack1 1: tst (sp)+ jmp elist cvsw: iocv; iicv / 0 locv; licv / 4 focv; ficv / 10 docv; dicv / 14 gocv; gicv / 20 eocv; eicv / 24 aocv; aicv / 30 xocv; xicv / 34 hocv; hicv / 40 qocv; qicv / 44 crack1: jmp crack err1: jsr r5,rerr; 109. sys exit beq 4b cmp r0,$'. bne err1 jsr r5,gnum mov r0,ndig 2: inc itmfnd 3: add $cvsw,(sp) tst rdflg beq 1f add $2,(sp) 1: mov *(sp)+,-(sp) 1: tst ngflg bne 2f jsr r5,getitm br 1f 2: clr gflg jsr r5,*(sp) dec rep bgt 1b tst (sp)+ br crack1 1: tst (sp)+ jmp elist cvsw: iocv; iicv / 0 locv; licv / 4 focv; ficv / 10 docv; dicv / 14 gocv; gicv / 20/ / / io3 -- Fortran I/O .globl getbuf .globl chkunit .globl creatf .globl openf setio: mov r1,unit jsr r5,chkunit movb utable(r1),r0 beq 1f bpl 2f mov r1,r0 asl r0 mov btable(r0),r0 mov r0,r2 br 4f 2: cmp (r5),r0 beq 3f jsr r5,rerr; 101. / inconsistent use of unit sys exit 1: mov r1,-(sp) clr r0 dvd $10.,r0 swab r1 bis r1,r0 add $"00,r0 mov r0,filnam+4 mov (sp)+,r1 jsr r5,getbuf mov $filnam,r0 4: movb (r5),utable(r1) bit $1,(r5) bne 2f jsr r5,creatf br 3f 2: jsr r5,openf 3: tst (r5)+ asl r1 mov btable(r1),buffer rts r5 getbuf: mov $utable,r0 mov $btable,r2 1: tstb (r0)+ beq 2f tst (r2)+ br 3f 2: tst (r2)+ beq 3f mov -(r2),r0 clr (r2) mov r0,r2 br 2f 3: cmp r0,$utable+20. blo 1b mov bufp,r2 add $134.,bufp mov bufp,0f sys break; 0:.. 2: mov r1,r0 asl r0 mov r2,btable(r0) mov r2,buffer rts r5 chkunit: cmp r1,$20. blo 1f jsr r5,rerr; 100. / illegal unit number sys exit 1: rts r5 creatf: cmp unit,$6 bne 2f mov $1,r0 br 1f 2: mov r0,0f sys creat; 0:..; 666 bec 1f jsr r5,rerr; 102. / create error sys exit 1: mov r2,-(sp) mov r0,(r2)+ clr (r2)+ clr (r2)+ mov r2,-(r2) mov (sp)+,r2 rts r5 openf: cmp unit,$5 bne 2f clr r0 br 1f 2: mov r0,0f sys open; 0:..; 0 bec 1f jsr r5,rerr; 103. / open error sys exit 1: mov r2,-(sp) mov r0,(r2)+ clr (r2)+ clr (r2)+ mov (sp)+,r2 rts r5 fputc: mov r1,-(sp) mov buffer,r1 dec 2(r1) bge 1f mov r0,-(sp) jsr pc,flush1 dec 2(r1) mov (sp)+,r0 1: movb r0,*4(r1) inc 4(r1) mov (sp)+,r1 rts r5 fflush: mov r1,-(sp) mov buffer,r1 jsr pc,flush1 mov (sp)+,r1 rts r5 flush1: mov r1,r0 add $6,r0 mov r0,-(sp) mov r0,0f neg r0 add 4(r1),r0 bhis 1f mov r0,0f+2 mov (r1),r0 sys write; 0:..; .. 1: mov (sp)+,4(r1) mov $128.,2(r1) rts pc fgetc: tst nlflg bne 4f mov r1,-(sp) mov buffer,r1 dec 2(r1) bge 1f mov r1,r0 add $6,r0 mov r0,0f mov r0,4(r1) mov (r1),r0 sys read; 0:..; 128. bes 2f tst r0 bne 3f 2: jsr r5,rerr; 104. / EOF on input sys exit 3: dec r0 mov r0,2(r1) 1: clr r0 bisb *4(r1),r0 inc 4(r1) mov (sp)+,r1 tst binflg bne 1f cmp r0,$'\n bne 1f 4: mov pc,nlflg mov $' ,r0 1: rts r5 gnum: mov r1,-(sp) clr r1 1: jsr r5,fmtchr cmp r0,$' / beq 1b sub $'0,r0 cmp r0,$9. bhi 1f mpy $10.,r1 add r0,r1 br 1b 1: mov r1,r0 mov (sp)+,r1 dec formp rts r5 switch: mov (r5)+,r1 1: tst (r1) beq 1f cmp r0,(r1)+ bne 1b tst (sp)+ jmp *(r1) 1: rts r5 fmtchr: movb *formp,r0 inc formp rts r5 getitm: tst itmflg bne 1f mov r5,-(sp) jmp *(r4)+ 1: clr itmflg tst (r5)+ rts r5 / just a fake, there's no carriage control fputcc: cmp $' ,r0 bne 1f inc nspace rts r5 1: mov r0,-(sp) 1: dec nspace blt 1f mov $' ,r0 jsr r5,fputc br 1b 1: clr nspace mov (sp)+,r0 beq 1f jsr r5,fputc 1: rts r5 eorec: mov unit,r0 bitb $1,utable(r0) bne 1f clr nspace mov $'\n,r0 jsr r5,fputc eorec1: clr r0 jsr r5,fputcc / cmp unit,$6 / tty output / bne 2f jsr r5,fflush 2: rts r5 1: tst nlflg bne 1f jsr r5,fgetc br 1b 1: clr nlflg rts r5 spaces: add r1,nspace rts r5 r5 / just a fake, there's no carriage control fputcc: cmp $' ,r0 bne 1f inc nspace rts r5 1: mov r0,-(sp) 1: dec nspace blt 1f mov $' ,r0 jsr r5,fputc br 1b 1: clr nspace mov (sp)+,r0 beq 1f jsr r5,fputc 1: rts r5 eorec: mov unit,r0 bitb $1,utable(r0) bne 1f clr nspace mov $'\n,r0 jsr r5,fputc eorec1: clr r0 jsr r5,fputcc / cmp unit,$6 / tty output / bne 2f jsr r5,fflush 2: rts r5 1: tst nlflg bne 1f jsr r5,fgetc br 1b 1: clr nlflg r/ / / io4 -- numeric output conversion qicv: hicv: tst rep ble 1f jsr r5,fgetc movb r0,*formp inc formp dec rep bgt hicv 1: rts r5 xicv: jsr r5,fgetc rts r5 gocv: mov pc,gflg jsr r5,getarg mov ndig,_ndigit jsr pc,ecvt tst r2 bmi eocv cmp r2,ndig bgt eocv mov ndig,-(sp) sub r2,ndig sub $4,width jsr r5,focv add $4,width add $4,nspace mov (sp)+,ndig rts r5 eocv: mov $'e,-(sp) br 1f docv: mov $'d,-(sp) 1: tst gflg bne 1f jsr r5,getarg 1: mov ndig,r1 add $6,r1 add nflg,r1 sub width,r1 bge 2f sub r1,nspace 2: tst nflg beq 2f mov $'-,r0 jsr r5,fputcc 2: mov ndig,r1 mov scale,r0 bgt 2f add r0,r1 br 3f 2: inc r1 3: mov r1,_ndigit jsr pc,ecvt mov r0,r1 mov r2,-(sp) mov scale,r2 sub r2,(sp) tst r2 bgt 2f mov $'0,r0 jsr r5,fputcc br 3f 2: movb (r1)+,r0 dec _ndigit jsr r5,fputcc sob r2,2b 3: mov $'.,r0 jsr r5,fputcc neg r2 ble 2f 3: mov $'0,r0 jsr r5,fputcc sob r2,3b 2: mov _ndigit,r2 ble 2f 3: movb (r1)+,r0 jsr r5,fputcc sob r2,3b 2: mov 2(sp),r0 jsr r5,fputcc mov (sp)+,r1 bge 2f mov $'-,r0 jsr r5,fputcc neg r1 br 3f 2: mov $'+,r0 jsr r5,fputcc 3: clr r0 div $10.,r0 add $'0,r0 jsr r5,fputcc mov r1,r0 add $'0,r0 jsr r5,fputcc tst (sp)+ rts r5 iocv: clr -(sp) clr ndig br 1f focv: mov $1,-(sp) 1: clr -(sp) tst gflg bne 1f jsr r5,getarg tst 2(sp) beq 1f mov scale,(sp) 1: mov ndig,_ndigit add (sp)+,_ndigit jsr pc,fcvt mov r0,r1 tst (sp) beq 1f tst gflg bne 1f add scale,r2 1: mov ndig,r0 add (sp),r0 add nflg,r0 tst r2 ble 1f add r2,r0 1: sub width,r0 bge 1f sub r0,nspace 1: tst nflg beq 1f mov $'-,r0 jsr r5,fputcc 1: tst r2 ble 2f 1: movb (r1)+,r0 jsr r5,fputcc sob r2,1b 2: tst (sp)+ beq 1f mov $'.,r0 jsr r5,fputcc 1: mov ndig,-(sp) ble 1f tst r2 bge 1f neg r2 2: mov $'0,r0 jsr r5,fputcc dec ndig ble 1f sob r2,2b 1: mov ndig,r2 ble 2f 1: movb (r1)+,r0 jsr r5,fputcc sob r2,1b 2: mov (sp)+,ndig rts r5 getarg: clr nflg setd cmpb itype,$'r beq 1f seti cmpb ilen,$4 bne 2f setl 2: cmpb ilen,$1 beq 3f movif *ilval,r0 br 2f 3: movb *ilval,r0 movif r0,fr0 br 2f 1: cmpb ilen,$4 bne 1f movof *ilval,r0 br 2f 1: movf *ilval,r0 2: cfcc bge 1f absf r0 mov $1,nflg 1: rts r5 jsr r5,fputcc 1: mov ndig,-(sp) ble 1f tst r2 bge 1f neg r2 2: mov $'0,r0 jsr r5,fputcc dec ndig ble 1f sob r2,2b 1: mov ndig,r2 ble 2f 1: movb (r1)+,r0 jsr r5,fputcc sob r2,1b 2: mov (sp)+,ndig rts r5 getarg: clr nflg setd cmpb itype,$'r beq 1f seti cmpb ilen,$4 bne/ / / io5 -- more conversions /.globl hocv /.globl qocv /.globl xocv /.globl aocv /.globl locv / /.globl fmtchr /.globl fputcc /.globl rep /.globl formp /.globl spaces /.globl ilen /.globl width /.globl ilval .globl rerr hocv: jsr r5,fmtchr tst r0 beq 2f jsr r5,fputcc dec rep bgt hocv rts r5 2: jsr r5,rerr; 111. sys exit qocv: mov formp,-(sp) 1: jsr r5,fmtchr tst r0 beq 2f cmp r0,$'" beq 2f jsr r5,fputcc br 1b 2: dec rep ble 1f mov (sp),formp br 1b 1: tst (sp)+ rts r5 xocv: mov $1,r1 jsr r5,spaces rts r5 aocv: movb ilen,r1 sub width,r1 neg r1 bpl 1f clr r1 1: jsr r5,spaces mov ilval,r2 mov width,r1 cmpb r1,ilen ble 2f movb ilen,r1 2: movb (r2)+,r0 jsr r5,fputcc dec r1 bgt 2b rts r5 locv: mov width,r1 dec r1 jsr r5,spaces mov $'f,r0 movb ilen,r1 mov ilval,r2 2: tstb (r2)+ bne 1f dec r1 bgt 2b br 2f 1: mov $'t,r0 2: jsr r5,fputcc rts r5 0,$'" beq 2f jsr r5,fputcc br 1b 2: dec rep ble 1f mov (sp),formp br 1b 1: tst (sp)+ rts r5 xocv: mov / / / io6 -- input conversions /.globl aicv /.globl gicv / /.globl ilval /.globl width /.globl ilen /.globl fgetc /.globl itype /.globl nlflg /.globl gcflg aicv: mov ilval,r1 movb width,r2 movb ilen,r0 mov r0,-(sp) 1: cmp r2,(sp) ble 1f jsr r5,fgetc dec r2 br 1b 1: tst r2 ble 1f jsr r5,fgetc movb r0,(r1)+ dec r2 dec (sp) br 1b 1: tst (sp) ble 1f movb $' ,(r1)+ dec (sp) br 1b 1: tst (sp)+ rts r5 licv: mov width,twidth setd seti clrf fr0 1: jsr r5,fgetcn cmp r0,$'t beq 2f cmp r0,$'T beq 2f cmp r0,$'1 beq 2f cmp r0,$', beq 1f br 1b 2: movif $1,fr0 br 1b 1: br storin iicv: clr ndig clr iscale br 1f ficv: eicv: dicv: mov scale,iscale 1: mov width,twidth br 1f gicv: tst width bgt ficv mov $16383.,twidth clr ndig mov pc,gcflg mov scale,iscale br 2f 1: clr gcflg 2: jsr r5,gatof storin: cmpb itype,$'r beq 1f cmpb ilen,$1 beq 3f cmpb ilen,$4 bne 2f setl 2: movfi fr0,*ilval rts r5 3: movfi fr0,r0 movb r0,*ilval rts r5 1: cmpb ilen,$8. beq 2f setf 2: movf fr0,*ilval rts r5 gatof: setd seti movif $10.,fr3 clr r2 clrf fr0 clr -(sp) 1: jsr r5,fgetcn cmp $' ,r0 bne 1f tst nlflg beq 1b tst (sp)+ rts r5 1: cmp r0,$'+ beq 1f cmp r0,$'- bne 2f inc (sp) 1: jsr r5,fgetcn 2: cmp $' ,r0 bne 3f tst gcflg bne 3f mov $'0,r0 3: sub $'0,r0 cmp r0,$9. bhi 2f mulf fr3,fr0 movif r0,fr1 addf fr1,fr0 dec r1 br 1b 2: add $'0,r0 cmp r0,$'. bne 1f inc r2 clr r1 br 1b 1: mov r3,-(sp) clr r3 cmp r0,$'d beq 3f cmp r0,$'+ beq 3f cmp r0,$'- beq 3f cmp r0,$'e bne 2f 3: clr iscale jsr r5,atoi 2: tst r2 bne 1f mov ndig,r1 neg r1 1: movf fr3,fr2 add r3,r1 sub iscale,r1 mov (sp)+,r3 tst r1 beq 1f bpl 3f neg r1 mov pc,-(sp) br 2f 3: clr -(sp) 2: dec r1 ble 2f mulf fr3,fr2 br 2b 2: tst (sp)+ bne 2f mulf fr2,fr0 br 1f 2: divf fr2,fr0 1: tst (sp)+ beq 1f negf r0 1: cmp r0,$', beq 1f cmp $' ,r0 beq 1f jsr r5,rerr; 110. 1: rts r5 atoi: clr -(sp) cmp r0,$'+ beq 1f cmp r0,$'- beq 3f jsr r5,fgetcn cmp r0,$'+ beq 1f cmp r0,$'- bne 2f 3: inc (sp) 1: jsr r5,fgetcn 2: sub $'0,r0 cmp r0,$'9. bhi 2f mpy $10.,r3 add r0,r3 br 1b 2: add $'0,r0 tst (sp)+ beq 1f neg r3 1: rts r5 fgetcn: tst twidth bgt 1f mov $',,r0 rts r5 1: jsr r5,fgetc dec twidth rts r5 tst (sp)+ bne 2f mulf fr2,fr0 br 1f 2: divf fr2,fr0 1: tst (sp)+ beq 1f negf r0 1: cmp r0,$', beq 1f cmp $' ,r0 beq 1f jsr r5,rerr; 110. 1: rts r5 atoi: clr -(sp) cmp r0,$'+ beq 1f cmp r0,$'- beq 3f jsr r5,fgetcn c/ / / Fortran binary I/O .globl iowu .globl ioru .globl rewi .globl enfl iowu: tst (sp)+ mov (sp)+,r1 / unit number jsr r5,setio; 42 1: jsr r5,getitm br 1f movb ilen,r1 mov ilval,r2 2: movb (r2)+,r0 jsr r5,fputc sob r1,2b br 1b 1: jsr r5,fflush jmp *(r4)+ ioru: tst (sp)+ mov (sp)+,r1 / unit number jsr r5,setio; 41 clr nlflg mov pc,binflg 1: jsr r5,getitm br 1f movb ilen,r1 mov ilval,r2 2: jsr r5,fgetc movb r0,(r2)+ sob r1,2b br 1b 1: jmp *(r4)+ rewi: enfl: tst (sp)+ mov (sp)+,r1 / unit number jsr r5,chkunit clrb utable(r1) asl r1 mov *btable(r1),r0 cmp r0,$1 bhi 1f sys seek; 0; 0 jmp *(r4)+ 1: sys close jmp *(r4)+ br 1f movb ilen,r1 mov ilval,r2 2: movb (r2)+,r0 jsr r5,fputc sob r1,2b br 1b 1: jsr r5,fflush jmp *(r4)+ ioru: tst (sp)+ mov (sp)+,r1 / unit number jsr r5,setio; 41 clr nlflg mov pc,binflg 1: jsr r5,getitm br 1f movb ilen,r1 mov ilval,r2 2: jsr r5,fgetc movb r0,(r2)+ sob r1,2b br 1b 1: jmp *(r4)+ rewi: enfl: tst (sp)+ mov/ / / iox -- io variables .globl _nocr .globl utable .globl btable .globl ftable .globl _end .globl formp bufp: _end filnam: ; .even .bss gflg: .=.+2 formp: .=.+2 rdflg: .=.+2 nflg: .=.+2 unit: .=.+2 buffer: .=.+2 slcnt: .=.+2 itype: .=.+1 ilen: .=.+1 ilval: .=.+2 width: .=.+2 twidth: .=.+2 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2 ngflg: .=.+2 iscale: .=.+2 nlflg: .=.+2 _nocr: .=.+2 .globl btable .globl ftable .globl _end .globl formp bufp: _end filnam: ; .even .bss gflg: .=.+2 formp: .=.+2 rdflg: .=.+2 nflg: .=.+2 unit: .=.+2 buffer: .=.+2 slcnt: .=.+2 itype: .=.+1 ilen: .=.+1 ilval: .=.+2 width: .=.+2 twidth: .=.+2 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / abs & dabs fortran functions .globl abs. .globl dabs. .globl retrn .globl temp dabs.: temp .+2 setd br 1f abs.: temp .+2 setf 1: movf *2(r3),r0 absf r0 movf r0,temp jmp retrn flg: .=.+2 unit: .=.+2 buffer: .=.+2 slcnt: .=.+2 itype: .=.+1 ilen: .=.+1 ilval: .=.+2 width: .=.+2 twidth: .=.+2 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / aimag fortran function .globl aimag. .globl rval8p .globl retrn .globl temp aimag.: temp rval8p; 2 .+2 setf tstf (sp)+ movf (sp)+,r0 movf r0,temp jmp retrn vf r0,temp jmp retrn flg: .=.+2 unit: .=.+2 buffer: .=.+2 slcnt: .=.+2 itype: .=.+1 ilen: .=.+1 ilval: .=.+2 width: .=.+2 twidth: .=.+2 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / aint fortran function .globl aint. .globl temp one = 40200 .globl retrn aint.: temp .+2 setf movf *2(r3),r0 modf $one,r0 movf r1,temp jmp retrn jmp retrn vf r0,temp jmp retrn flg: .=.+2 unit: .=.+2 buffer: .=.+2 slcnt: .=.+2 itype: .=.+1 ilen: .=.+1 ilval: .=.+2 width: .=.+2 twidth: .=.+2 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / alog & log fortran functions .globl alog. .globl dlog. .globl log .globl retrn .globl rerr .globl temp dlog.: temp .+2 setd br 1f alog.: temp .+2 setf 1: seti movf *2(r3),r0 jsr pc,log bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 1 ilen: .=.+1 ilval: .=.+2 width: .=.+2 twidth: .=.+2 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / alog10 & dlog10 fortran functions .globl dlog10. .globl alog10. .globl log .globl retrn .globl rerr .globl temp dlog10.:temp .+2 setd br 1f alog10.:temp .+2 setf 1: movf *2(r3),r0 jsr pc,log bes 1f mulf const,r0 movf r0,temp jmp retrn 1: jsr r5,rerr; 1 const: 37736;55730;124467;24146 ndig: .=.+2 pbuf: .=.+10 ppar: .=.+2 llp: .=.+2 llpcnt: .=.+2 itmflg: .=.+2 nspace: .=.+2 gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / max0 & amax0 fortran functions .globl amax0. .globl max0. .globl retrn .globl temp max0.: temp .+2 mov pc,r2 br 1f amax0.: temp .+2 clr r2 1: setf setl mov *2(sp),r0 / arg count mov r3,r1 tst (r1)+ / argpp movif *(r1)+,r1 br 2f 1: movif *(r1)+,r0 cmpf r0,r1 cfcc ble 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn gcflg: .=.+2 binflg: .=.+2 utable: .=.+20. btable: .=.+40. ftable: .=.+2. rep: .=.+2 scale: .=.+2 itmfnd: .=.+2/ / / max1, amax1 & dmax1 fortran functions .globl amax1. .globl dmax1. .globl max1. .globl retrn .globl temp max1.: temp .+2 setl setf mov pc,r2 / integer flag br 2f dmax1.: temp .+2 setd br 1f amax1.: temp .+2 setf 1: clr r2 / integer flag 2: mov *2(sp),r0 / arg count mov r3,r1 tst (r1)+ / argpp movf *(r1)+,r1 br 2f 1: movf *(r1)+,r0 cmpf r0,r1 cfcc ble 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn .=.+2 itmfnd: .=.+2/ / / min0 & amin0 fortran functions .globl amin0. .globl min0. .globl retrn .globl temp min0.: temp .+2 mov pc,r2 br 1f amin0.: temp .+2 clr r2 1: setf setl mov *2(sp),r0 / arg count mov r3,r1 tst (r1)+ / argpp movif *(r1)+,r1 br 2f 1: movif *(r1)+,r0 cmpf r0,r1 cfcc bge 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn ,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn .=.+2 itmfnd: .=.+2/ / / min1, amin1 & dmin1 fortran functions .globl amin1. .globl dmin1. .globl min1. .globl retrn .globl temp min1.: temp .+2 setl setf mov pc,r2 br 2f dmin1.: temp .+2 setd br 1f amin1.: temp .+2 setf 1: clr r2 2: mov *2(sp),r0 / arg count mov r3,r1 tst (r1)+ / argpp movf *(r1)+,r1 br 2f 1: movf *(r1)+,r0 cmpf r0,r1 cfcc bge 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn 1: movfi r1,temp 2: jmp retrn .=.+2 itmfnd: .=.+2/ / / amod & dmod fortran functions .globl amod. .globl dmod. .globl retrn one = 40200 .globl temp .globl rerr dmod.: temp .+2 setd br 1f amod.: temp .+2 setf 1: cmp *2(sp),$2 bne 1f movf *2(r3),r0 movf r0,r2 movf *4(r3),r1 divf r1,r2 modf $one,r2 mulf r1,r3 subf r3,r0 movf r0,temp jmp retrn 1: jsr r5,rerr; 2 cmpf r0,r1 cfcc bge 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn 1: movfi r1,temp 2: jmp retrn .=.+2 itmfnd: .=.+2/ / / atan & datan fortran functions .globl atan. .globl datan. .globl atan .globl retrn .globl temp datan.: temp .+2 setd br 1f atan.: temp .+2 setf 1: movf *2(r3),r0 jsr pc,atan movf r0,temp jmp retrn r0,r2 movf *4(r3),r1 divf r1,r2 modf $one,r2 mulf r1,r3 subf r3,r0 movf r0,temp jmp retrn 1: jsr r5,rerr; 2 cmpf r0,r1 cfcc bge 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn 1: movfi r1,temp 2: jmp retrn .=.+2 itmfnd: .=.+2/ / / atan2 & datan2 fortran functions .globl atan2. .globl datan2. .globl retrn .globl rerr .globl temp .globl atan2 datan2.: temp .+2 setd br 1f atan2.: temp .+2 setf 1: cmp *2(sp),$2 bne 1f movf *2(r3),r0 movf *4(r3),r1 jsr pc,atan2 movf r0,temp jmp retrn 1: jsr r5,rerr; 3 r0,temp jmp retrn 1: jsr r5,rerr; 2 cmpf r0,r1 cfcc bge 2f movf r0,r1 2: dec r0 bgt 1b tst r2 bne 1f movf r1,temp br 2f 1: movfi r1,temp 2: jmp retrn 1: movfi r1,temp 2: jmp retrn .=.+2 itmfnd: .=.+2/ / / cabs fortran function .globl cabs. .globl dcabs. .globl sqrt .globl retrn .globl rerr .globl temp dcabs.: temp .+2 setd br 1f cabs.: temp .+2 setf 1: mov 2(r3),r1 movf (r1)+,r0 movf (r1)+,r1 jsr pc,hypot bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 4 hypot: movf fr1,-(sp) absf fr0 absf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc movf (sp)+,fr1 rts pc one = 40200 obl cabs. .globl dcabs. .globl sqrt .globl retrn .globl rerr .globl temp dcabs.: temp .+2 setd br 1f cabs.: temp .+2 setf 1: mov 2(r3),r1 movf (r1)+,r0 movf (r1)+,r1 jsr pc,hypot bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 4 hypot: movf fr1,-(sp) absf fr0 absf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function ccos(z1) complex ccos, z1, z2 dimension dummy(2) equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = exp(b) d = 1.0/c b = sin(a)*(d-c)/2.0 a = cos(a)*(c+d)/2.0 ccos = z2 return end +,r1 jsr pc,hypot bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 4 hypot: movf fr1,-(sp) absf fr0 absf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function cexp(z1) complex cexp, z1, z2 dimension dummy(2) equivalence(a,z2,dummy(1)),(b,dummy(2)) z2 = z1 c = exp(a) a = c * cos(b) b = c * sin(b) cexp = z2 return end ccos = z2 return end +,r1 jsr pc,hypot bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 4 hypot: movf fr1,-(sp) absf fr0 absf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function clog(z1) complex clog, z1, z2 dimension dummy(2) equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = cabs(z2) b = atan2(b, a) a = alog(c) clog = z2 return end ccos = z2 return end +,r1 jsr pc,hypot bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 4 hypot: movf fr1,-(sp) absf fr0 absf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / cmplx fortran function .globl cmplx. .globl dcmplx. .globl retrn .globl temp .globl rerr dcmplx.:temp .+2 setd br 1f cmplx.: temp .+2 setf 1: cmp *2(sp),$2 bne 1f mov r3,r1 tst (r1)+ movf *(r1)+,r0 movf *(r1)+,r1 mov $temp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / conjg fortran function .globl conjg. .globl rval8p .globl retrn .globl temp conjg.: temp rval8p; 2 .+2 setf movf (sp)+,r0 movf r0,temp movf (sp)+,r0 negf r0 movf r0,temp+4 jmp retrn + movf *(r1)+,r0 movf *(r1)+,r1 mov $temp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / cos & dcos fortran functions .globl cos. .globl dcos. .globl cos .globl retrn .globl temp dcos.: temp .+2 setd br 1f cos.: temp .+2 setf 1: movf *2(r3),r0 jsr pc,cos movf r0,temp jmp retrn *(r1)+,r0 movf *(r1)+,r1 mov $temp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function csin(z1) complex csin, z1, z2 dimension dummy(2) equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = exp(b) d = 1.0/c b = cos(a)*(c-d)/2.0 a = sin(a)*(c+d)/2.0 csin = z2 return end trn *(r1)+,r0 movf *(r1)+,r1 mov $temp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function csqrt(z1) complex csqrt, z1, z2 dimension dummy(2) equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = cabs(z2) c = sqrt(c) b = atan2(b, a)/2.0 a = c*cos(b) b = c*sin(b) csqrt = z2 return end 0 movf *(r1)+,r1 mov $temp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / dble fortran function .globl dble. .globl rval4p .globl lval .globl r4r8 .globl gas8 .globl retrn .globl temp dble.: temp lval; temp rval4p; 2 r4r8 gas8 retrn (b) b = c*sin(b) csqrt = z2 return end 0 movf *(r1)+,r1 mov $temp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function dccos(z1) double complex dccos, z1, z2 double precision dummy(2), a, b, c, d equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = dexp(b) d = 1.0d0/c b = dsin(a)*(d-c)/2.0d0 a = dcos(a)*(c+d)/2.0d0 dccos = z2 return end mp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function cexp(z1) double complex cexp, z1, z2 double precision dummy(2), a, b equivalence(a,z2,dummy(1)),(b,dummy(2)) z2 = z1 c = dexp(a) a = c * dcos(b) b = c * dsin(b) cexp = z2 return end a)*(c+d)/2.0d0 dccos = z2 return end mp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function dclog(z1) double complex z1, z2, dclog double precision a,b,c double precision dummy(2) equivalence (a,z2,dummy(1)), (b,dummy(2)) z2=z1 c=dcabs(z2) b=datan2(b,a) a=dlog(c) dclog=z2 return end 0d0 dccos = z2 return end mp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function dcsin(z1) double complex dcsin, z1, z2 double precision dummy(2), a, b, c, d equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = dexp(b) d = 1.0d0/c b = dcos(a)*(c-d)/2.0d0 a = dsin(a)*(c+d)/2.0d0 dcsin = z2 return end mp,r1 movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov function dcsqrt(z1) double complex dcsqrt, z1, z2 double precision dummy(2), a, b, c equivalence (a,z2,dummy(1)), (b,dummy(2)) z2 = z1 c = dcabs(z2) c = dsqrt(c) b = datan2(b, a)/2.0d0 a = c*dcos(b) b = c*dsin(b) dcsqrt = z2 return end movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / dim fortran function .globl dim. .globl retrn .globl temp .globl rerr / dim.: temp .+2 setf cmp *2(sp),$2 bne 2f movf *2(r3),r0 subf *4(r3),r0 cfcc bge 1f clrf r0 1: movf r0,temp jmp retrn 2: jsr r5,rerr; 7. t = z2 return end movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / dimag fortran function .globl dimag. .globl rval16p .globl retrn .globl temp dimag.: temp rval16p; 2 .+2 setd tstf (sp)+ movf (sp)+,r0 movf r0,temp jmp retrn rf r0 1: movf r0,temp jmp retrn 2: jsr r5,rerr; 7. t = z2 return end movf r0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / exp & dexp fortran functions .globl exp. .globl dexp. .globl exp .globl retrn .globl rerr .globl temp dexp.: temp .+2 setd br 1f exp.: temp .+2 setf 1: seti movf *2(r3),r0 jsr pc,exp bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 8. 0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / float fortran function .globl float. .globl rval4p .globl lval .globl gas4 .globl i4r4 .globl retrn .globl temp float.: temp lval; temp rval4p; 2 i4r4 gas4 retrn vf *2(r3),r0 jsr pc,exp bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 8. 0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / iabs fortran function .globl iabs. .globl retrn .globl temp iabs.: temp .+2 setl setd movif *2(r3),r0 absf r0 movfi r0,temp jmp retrn l4p; 2 i4r4 gas4 retrn vf *2(r3),r0 jsr pc,exp bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 8. 0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / idim fortran function .globl idim. .globl retrn .globl rerr .globl temp idim.: temp .+2 setd setl cmp *2(sp),$2 bne 2f movif *2(r3),r0 movif *4(r3),r1 subf r1,r0 cfcc bge 1f clrf r0 1: movfi r0,temp jmp retrn 2: jsr r5,rerr; 9. 8. 0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / idint fortran function .globl idint. .globl retrn .globl temp idint.: temp .+2 setd setl movf *2(r3),r0 movfi r0,temp jmp retrn r3),r0 movif *4(r3),r1 subf r1,r0 cfcc bge 1f clrf r0 1: movfi r0,temp jmp retrn 2: jsr r5,rerr; 9. 8. 0,(r1)+ movf r1,(r1)+ jmp retrn 1: jsr r5,rerr; 6. bsf fr1 cmpf fr0,fr1 cfcc bne 1f movf $one,fr0 br 3f 1: blt 2f movf fr0,-(sp) movf fr1,fr0 movf (sp)+,fr1 2: divf fr1,fr0 mulf fr0,fr0 3: addf $one,fr0 jsr pc,sqrt mulf fr1,fr0 cfcc mov/ / / catch runtime errors: / if (ierror(errno)) goto place / on call, returns 0 / on occurrence of error, returns non-zero ESIZE = 14. .globl ierror. .globl erret .globl rerr .globl ent,lin,disp .globl retrn ierror.:zero .+2 mov 2(r3),r0 mov 2(r0),r1 mov $errbuf,r0 1: cmp r0,cerrp blo 2f cmp cerrp,$eerbuf blo 3f jsr r5,rerr; 120. 3: add $ESIZE,cerrp br 1f 2: cmp r1,(r0) beq 1f add $ESIZE,r0 br 1b 1: mov r1,(r0)+ mov r3,(r0)+ mov 2(sp),(r0)+ mov 4(sp),(r0)+ mov 6(sp),(r0)+ mov 10(sp),(r0)+ mov 12(sp),(r0)+ cmp r1,$113. bne 1f sys signal; 2; intrp 1: jmp retrn intrp: sys signal; 2; intrp jsr r5,rerr; 113. .data erret: jmp 9f .text 9: mov $errbuf,r0 1: cmp (r0),r1 beq 1f add $ESIZE,r0 cmp r0,cerrp blo 1b rts pc 1: add $ESIZE,r0 mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / ifix & int fortran functions .globl ifix. .globl int. .globl lval .globl r4i4 .globl gas4 .globl rval4p .globl retrn .globl temp int.: ifix.: temp lval; temp rval4p; 2 r4i4 gas4 retrn q 1f add $ESIZE,r0 cmp r0,cerrp blo 1b rts pc 1: add $ESIZE,r0 mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / isign fortran function .globl isign. .globl retrn .globl rerr .globl temp isign.: temp .+2 setd setl cmp *2(sp),$2 bne 2f movif *2(r3),r0 absf r0 movif *4(r3),r1 cfcc bge 1f negf r0 1: movfi r0,temp jmp retrn 2: jsr r5,rerr; 10. dd $ESIZE,r0 mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / mod fortran function .globl mod. .globl retrn .globl temp one = 40200 .globl rerr mod.: temp .+2 setd setl cmp *2(sp),$2 bne 1f movif *2(r3),r0 movf r0,r2 movif *4(r3),r1 divf r1,r2 modf $one,r2 mulf r1,r3 subf r3,r0 movfi r0,temp jmp retrn 1: jsr r5,rerr; 11. v -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / real & dreal fortran function .globl real. .globl dreal. .globl retrn .globl temp dreal.: temp .+2 setd br 1f real.: temp .+2 setf 1: movf *2(r3),r0 movf r0,temp jmp retrn ivf r1,r2 modf $one,r2 mulf r1,r3 subf r3,r0 movfi r0,temp jmp retrn 1: jsr r5,rerr; 11. v -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / sign & dsign fortran functions .globl sign. .globl dsign. .globl retrn .globl temp .globl rerr dsign.: temp .+2 setd br 1f sign.: temp .+2 setf 1: cmp *2(sp),$2 bne 2f movf *2(r3),r0 absf r0 tstf *4(r3) cfcc bge 1f negf r0 1: movf r0,temp jmp retrn 2: jsr r5,rerr; 12. sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / sin & dsin fortran functions .globl sin. .globl dsin. .globl sin .globl retrn .globl temp dsin.: temp .+2 setd br 1f sin.: temp .+2 setf 1: movf *2(r3),r0 jsr pc,sin movf r0,temp jmp retrn 0 tstf *4(r3) cfcc bge 1f negf r0 1: movf r0,temp jmp retrn 2: jsr r5,rerr; 12. sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / sngl fortran function .globl sngl. .globl rval8p .globl lval .globl r8r4 .globl gas4 .globl retrn .globl temp sngl.: temp lval; temp rval8p; 2 r8r4 gas4 retrn sr pc,sin movf r0,temp jmp retrn 0 tstf *4(r3) cfcc bge 1f negf r0 1: movf r0,temp jmp retrn 2: jsr r5,rerr; 12. sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp/ / / sqrt & dsqrt fortran functions .globl sqrt. .globl dsqrt. .globl sqrt .globl retrn .globl rerr .globl temp dsqrt.: temp .+2 setd br 1f sqrt.: temp .+2 setf 1: movf *2(r3),r0 jsr pc,sqrt bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 13. ,temp jmp retrn 2: jsr r5,rerr; 12. sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp function tanh(a) b = exp(a) c = 1.0/b tanh = (b-c)/(b+c) return end qrt .globl retrn .globl rerr .globl temp dsqrt.: temp .+2 setd br 1f sqrt.: temp .+2 setf 1: movf *2(r3),r0 jsr pc,sqrt bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 13. ,temp jmp retrn 2: jsr r5,rerr; 12. sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(sp.globl ctime., retrn, temp ctime.: temp .+2 sys time clr temp mov r0,temp+2 setd setl movif temp,fr0 mulf $44200,fr0 mov r1,temp+2 movif temp,fr1 addf fr1,fr0 movf fr0,temp jmp retrn pc,sqrt bes 1f movf r0,temp jmp retrn 1: jsr r5,rerr; 13. ,temp jmp retrn 2: jsr r5,rerr; 12. sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov $one,-(sp) mov -(r0),r3 jmp retrn .data one: 77777; 177777 zero: 0; 0 cerrp: errbuf .bss errbuf: .=.+[5*ESIZE] eerbuf: 0)+ mov 6(sp),(r0)+ mov 10(spstatement too long syntax error in type statement redeclaration missing ( in array declarator syntax error in dimension statement inappropriate or gratuitous array declarator syntax error in subscript bound illegal character common variable is a parameter or already in common common syntax error subroutine/blockdata/function not first statement subroutine/function syntax error block data syntax error redeclaration in external external syntax error implicit syntax error subscript on non-array incorrect subscript count subscript out of range subscript syntax error DATA syntax error DATA semantics error equivalence inconsistency equivalence syntax error separate common blocks equivalenced common block illegally extended by equivalence common inconsistency created by equivalence DATA table overflow () imbalance in expression expression syntax error illegal variable in equivalence Storage initialized twice by DATA non array/function used with subscripts/arguments use of undeclared variable goto syntax error illegal return continue, return, stop, call, end, or pause syntax error assign syntax error if syntax error I/O syntax error do or I/O iteration error do end missing illegal statement in block data multiply defined labels undefined label dimension mismatch expression syntax error end of statement in hollerith constant array too large B table overflow unrecognized statement unction used with subscripts/arguments use of undeclared variable goto syntax error illeg/ call getarg(n, array [, nword] ) / / fill in the array with the n-th argument to the routine. / array is integer. / n counts from 1 for the file name (first) arg / if nword is specifies it gives the max number / of words to fill in / If no nword is given the array ends with at least one blank. / if nword is given the array is blank-padded to that length. / iargc(dummy) returns the number of arguments / (1-origin) .globl getarg., iargc. .globl retrn, temp .comm argp,2 getarg.: temp .+2 clr temp clr temp+2 mov $512.,r2 cmp *2(sp),$3 blt 1f mov 6(r3),r2 mov 2(r2),r2 asl r2 asl r2 1: mov 4(r3),r4 mov 2(r3),r1 mov 2(r1),r1 mov argp,r0 cmp r1,(r0) bgt 1f asl r1 add r0,r1 mov (r1),r1 2: tst r2 ble 1f movb (r1)+,(r4)+ beq 2f dec r2 inc temp+2 br 2b 2: dec r4 1: movb $' ,(r4)+ dec r2 bit $3,r2 bne 1b cmp r2,$256. bge 1f tst r2 bgt 1b 1: jmp retrn iargc.: temp .+2 clr temp mov *argp,temp+2 jmp retrn rgc. .globl retrn, temp .comm argp,2 getarg.: temp .+2 clr temp clr / / / fortran nice subroutine .globl nice. .globl retrn, temp nice.: temp .+2 mov $16.,r0 tst *2(sp) beq 1f mov 2(r3),r0 mov 2(r0),r0 1: sys nice jmp retrn sl r1 add r0,r1 mov (r1),r1 2: tst r2 ble 1f movb (r1)+,(r4)+ beq 2f dec r2 inc temp+2 br 2b 2: dec r4 1: movb $' ,(r4)+ dec r2 bit $3,r2 bne 1b cmp r2,$256. bge 1f tst r2 bgt 1b 1: jmp retrn iargc.: temp .+2 clr temp mov *argp,temp+2 jmp retrn rgc. .globl retrn, temp .comm argp,2 getarg.: temp .+2 clr temp clr / / copyright 1972 bell telephone laboratories inc. / / openr, openw-- / / call open(r|w) (string, iunit) / or, / call open(r|w) (argno, iunit) / where argno is an argument number (0 is command name) .globl openr. .globl openw. .globl utable .globl btable .globl ftable .globl getbuf .globl fopen .globl fcreat openr.: temp .+2 mov pc,-(sp) br 1f openw.: temp .+2 clr -(sp) 1: mov 4(r3),r1 mov 2(r1),r1 jsr r5,chkunit tstb utable(r1) beq 1f jsr r5,rerr; 101. sys exit 1: jsr r5,getbuf mov 2(r3),r0 mov 2(r0),r0 cmp r0,$32. bhi 1f cmp r0,*argp bhi err asl r0 add argp,r0 br 2f 1: tst (sp)+ beq 1f movb $1,utable(r1) gno, iunit) / where argno is an argument number (0 is command name) .globl openr. .globl openw. .globl utable .globl btable .globl ftable .globl getbuf .globl fopen .globl fcreat openr.: temp .+2 mov pc,-(sp) br 1f openw.: temp .+2 clr -(sp) 1: mov 4(r3),r1 mov 2(r1),r1 jsr r5,chkunit tstb utable(r1) beq 1f jsr r5,rerr; 101. sys exit 1: jsr r5,getbuf mov 2(/ fortran random number generator. / either single or double prec. .globl rand. .globl retrn rand.: value .+2 tst first bne 1f sys time mov r0,seed1 mov r1,seed2 inc first 1: mov seed1,r1 jsr pc,ran mov r1,seed1 tst r0 beq 1b seti setd movif r0,fr0 mov seed2,r1 jsr pc,ran mov r1,seed2 movif r0,fr1 addf fr1,fr0 divf $44200,fr0 movf fr0,value jmp retrn ran: mpy $13077.,r1 add $6925.,r1 mov r1,r0 bic $100000,r0 rts pc .bss first: .=.+2 seed1: .=.+2 seed2: .=.+2 value: .=.+8 2(/ / / move, line sct = 2 / fortran vt0 interfaces / erase screen erase.: temp .+2 jsr pc,setfil mov f,r0 sys write; erase; 2 jmp retrn / move(x, y) / / sets current x,y to arguments / .globl move. .globl line. .globl erase. .globl frame. .globl arc. .globl circle. .globl temp .globl retrn frame.: temp .+2 jsr pc,setfil mov 2(r3),r0 movb 2(r0),frame+1 mov f,r0 sys write; frame; 2 jmp retrn move.: temp .+2 jsr pc,garg mov r0,x mov r1,y jmp retrn / line(x, y) / / plot vector from current x,y / to arguments, setting current / x,y when done to arguments / line.: temp .+2 jsr pc,garg mov r0,x1 mov r1,y1 movb $3,command mov f,r0 sys write; command; 9 mov x1,x mov y1,y jmp retrn / call circle(x, y, radius) / circle's center at x, y circle.:temp .+2 jsr pc,garg mov r0,x mov r1,y mov 6(r3),r0 mov 2(r0),r0 ash $2,r0 mov r0,x1 movb $5,command mov f,r0 sys write; command; 7 jmp retrn / call arc(xo, yo, x1, y1, x2, y2) / plot circle arc: origin xo,yo; / counterclockwise from x1,y1 to x2,y2 arc.: temp .+2 jsr pc,garg mov r0,x mov r1,y cmp (r3)+,(r3)+ jsr pc,garg mov r0,x1 mov r1,y1 cmp (r3)+,(r3)+ jsr pc,garg mov r0,x2 mov r1,y2 movb $6,command mov f,r0 sys write; command; 13. sub $8.,r3 jmp retrn setfil: tst f bne 1f sys creat; vt; 17 bes 9f mov r0,f 1: rts pc garg: jsr pc,setfil mov 2(r3),r0 mov 2(r0),r0 mov 4(r3),r1 mov 2(r1),r1 ash $2,r0 ash $2,r1 sub $2048.,r0 sub $2048.,r1 rts pc 9: mov $1,r0 sys write; bmes; emes-bmes sys exit frame: .byte 4,0 erase: .byte 1,1 .byte 0 vt: bmes: ; emes: .bss .=.+1 command:.=.+1 x: .=.+2 y: .=.+2 x1: .=.+2 y1: .=.+2 x2: .=.+2 y2: .=.+2 f: .=.+2 mand mov f,r0 sys write; command; 13. sub $8.,r3 jmp retrn setfil: tst f bne 1f sys creat; vt; 17 bes 9f mov r0,f 1: rts pc garg: jsr pc,setfil mov 2(r3),r0 mov 2(r0),r0 mov 4(r3),r1 mov 2(r1),r1 ash $2,r0 ash $2,r1 sub $2048.,r0 sub $2048.,r1 rts pc 9: mov $1,r0 sys write; bmes; emes-bmes sys exit / fortran random number generator. / either single or double prec. .globl rand., srand. .globl retrn srand.: value .+2 mov *2(r3),seed1 inc first jmp retrn rand.: value .+2 tst first bne 1f sys time mov r1,seed1 inc first 1: mov seed1,r1 jsr pc,ran mov r1,seed1 seti setd movif r0,fr0 divf $44000,fr0 movf fr0,value jmp retrn ran: mpy $13077.,r1 add $6925.,r1 mov r1,r0 bic $100000,r0 rts pc .bss first: .=.+2 seed1: .=.+2 value: .=.+8 $1,r0 sys write; bmes; emes-bmes sys exit / / / fortran random I/O .globl rread. .globl rwrite. .globl temp .globl retrn .globl rerr rread.: temp .+2 mov 2(r3),r0 mov 2(r0),0f mov rfin,r0 bne 1f sys open; rf; 0 bes 9f mov r0,rfin 1: sys seek; 0:..; 0 mov 4(r3),0f mov 6(r3),r0 mov 2(r0),0f+2 mov rfin,r0 sys read; 0:..; 0 jmp retrn rwrite.:temp .+2 mov 2(r3),r0 mov 2(r0),0f mov rfout,r0 bne 1f sys creat; rf; 17 bes 9f mov r0,rfout 1: sys seek; 0:..; 0 mov 4(r3),0f mov 6(r3),r0 mov 2(r0),0f+2 mov rfout,r0 sys write; 0:..; .. jmp retrn 9: jsr r5,rerr; 456. sys exit rf: .even rfin: .=.+2 rfout: .=.+2 temp .+2 mov 2(r3),r0 mov 2(r0),0f mov rfin,r0 bne 1f sys open; rf; 0 bes 9f mov r0,rfin 1: sys seek; 0:..; 0 mov 4(r3),0f mov 6(r3),r0 mov 2(r0),0f+2 mov rfin,r0 sys read; 0:..; 0 jmp retrn rwrite.:temp .+2 mov 2(r3),r0 mov 2(r0),0f mov rfout,r0 bne 1f sys creat; rf; 17 bes 9f mov r0,rfout 1: sys seek; 0:..; 0 mov 4(r3),0f mov 6(r3),r0 mov 2(r0),0f+2 mov rfout,r0 sys write; 0/ Fortran library-- setfil / call setfil(unit, 5hname ) .globl setfil. .globl getbuf .globl chkunit .globl retrn .globl utable .globl temp .globl rerr setfil.: temp .+2 mov 2(r3),r1 mov 2(r1),r1 jsr r5,chkunit tstb utable(r1) beq 1f jsr r5,rerr; 112. 1: jsr r5,getbuf movb $-1,utable(r1) mov 4(r3),r0 mov r2,r1 1: movb (r0)+,(r1) beq 1f cmpb $' ,(r1)+ bne 1b clrb -(r1) 1: jmp retrn mov r0,rfout 1: sys seek; 0:..; 0 mov 4(r3),0f mov 6(r3),r0 mov 2(r0),0f+2 mov rfout,r0 sys write; 0sleep = 35. .globl sleep. .globl retrn sleep.: horse .+2 mov r3,r1 tst (r1)+ mov (r1),r1 tst (r1)+ mov (r1),r0 sys sleep jmp retrn .bss horse: .=.+4 : temp .+2 mov 2(r3),r1 mov 2(r1),r1 jsr r5,chkunit tstb utable(r1) beq 1f jsr r5,rerr; 112. 1: jsr r5,getbuf movb $-1,utable(r1) mov 4(r3),r0 mov r2,r1 1: movb (r0)+,(r1) beq 1f cmpb $' ,(r1)+ bne 1b clrb -(r1) 1: jmp retrn mov r0,rfout 1: sys seek; 0:..; 0 mov 4(r3),0f mov 6(r3),r0 mov 2(r0),0f+2 mov rfout,r0 sys write; 0/ fortran to UNIX IO / .globl read. .globl write. .globl seek. .globl seek0. .globl open. .globl creat. .globl close. .globl unlink. .globl errno. indir = 0 / integer function read(f, a, n) / integer f, n / logical*1 a(n) / same as C read.: temp rval4p; 2 / f i4i2 lvalp; 4 / a rval4p; 6 / n i4i2 .+2 mov (sp)+,9f+4 mov (sp)+,9f+2 mov (sp)+,r0 sys indir; 9f jmp ret .data 9: sys read; ..; .. .text / integer function read(f, a, n) / integer f, n / logical*1 a(n) / same as C write.: temp rval4p; 2 / f i4i2 lvalp; 4 / a rval4p; 6 / n i4i2 .+2 mov (sp)+,9f+4 mov (sp)+,9f+2 mov (sp)+,r0 sys indir; 9f br ret .data 9: sys write; ..; .. .text / integer function seek(f, o, b) / integer f, o, b / same as C seek.: temp rval4p; 2 / f i4i2 rval4p; 4 / o i4i2 rval4p; 6 / b i4i2 .+2 mov (sp)+,9f+4 mov (sp)+,9f+2 mov (sp)+,r0 sys indir; 9f br ret / integer function seek0(f, n) / integer f, n / same as seek(f, n, 0) / but with 24 bit `n' seek0.: temp rval4p; 2 / f i4i2 rval4p; 4 / n .+2 mov (sp)+,r0 mov (sp),r1 bic $!777,(sp) ashc $-9.,r0 mov r1,9f+2 mov $3,9f+4 mov 2(sp),r0 sys indir; 9f / to block mov (sp)+,9f+2 mov $1,9f+4 mov (sp)+,r0 sys indir; 9f / to byte within block br ret .data 9: sys seek; ..; .. .text / integer function open(a, m) / logical*1 a(n) / integer m / same as C, name is ` ' terminated open.: temp lvalp; 2 / a rval4p; 4 / m i4i2 .+2 mov (sp)+,9f+4 mov (sp)+,r0 mov r0,9f+2 1: cmpb (r0)+,$' / bne 1b clrb -(r0) mov r0,-(sp) sys indir; 9f movb $' ,*(sp)+ br ret .data 9: sys open; ..; .. .text / integer function creat(a, m) / logical*1 a(n) / integer m / same as C, name is ` ' terminated creat.: temp lvalp; 2 / a rval4p; 4 / m i4i2 .+2 mov (sp)+,9f+4 mov (sp)+,r0 mov r0,9f+2 1: cmpb (r0)+,$' / bne 1b clrb -(r0) mov r0,-(sp) sys indir; 9f movb $' ,*(sp)+ br ret .data 9: sys creat; ..; .. .text / integer function close(f) / integer f / same as C close.: temp rval4p; 2 / f i4i2 .+2 mov (sp)+,r0 sys close br ret / integer function unlink(c) / logical*1 c(n) / same as C, name is ` ' terminated unlink.: temp lvalp; 2 .+2 mov (sp)+,r0 mov r0,9f+2 1: cmpb (r0)+,$' / bne 1b clrb -(r0) sys indir; 9f br ret .data 9: sys unlink; .. .text ret: bec 1f mov r0,error mov $-1,r0 1: mov r0,temp+2 sxt temp jmp retrn / error = errno / returns last error number errno.: temp .+2 mov error,r0 br ret .globl temp .globl retrn .globl rval4p .globl lvalp .globl i4i2 .bss error: .=.+2 (sp)+,r0 sys clos/ fortran runtime startup / calls main and provides error / messages .globl main .globl pdec .globl temp .globl rerr .globl trace .globl fptrap .comm erret,2 .comm argp,2 ldfps = 170100^tst sys signal; 4; fptrap ldfps $5400 sys signal; 8.; fperr mov sp,argp mov $main,r4 jmp *(r4)+ fperr: jsr r5,rerr; 998. rerr: mov (r5)+,r1 tst erret beq 1f jsr pc,erret 1: mov $2,r0 sys write; m1; m2-m1 jsr r5,pdec mov $2,r0 sys write; m2; 1 jsr pc,trace sys exit pdec: clr r0 div $10.,r0 mov r1,-(sp) mov r0,r1 beq 1f jsr r5,pdec 1: mov (sp)+,r0 add $'0,r0 movb r0,temp mov $2,r0 sys write; temp; 1 rts r5 m1: m2: <\n> .even .bss temp: .=.+16. ps = 170100^tst sys signal; 4; fptrap ldfps $5400 sys signal; 8.; fperr mov sp,argp mov $main,r4 jmp *(r4)+ fperr: jsr r5,rerr; 998. rerr: mov (r5)+,r1 tst erret beq 1f jsr pc,erret 1: mov $2,r0 sys write; m1; m2-m1 jsr r5,pdec mov $2,r0 sys write; m2; 1 jsr pc,trace sys exit pdec: clr r0 div $10.,r0 mov r1/ / / r1 -- fortran runtime .globl gas1 .globl gas2 .globl gas4 .globl gas8 .globl stop .globl lval .globl rval4 .globl rval8 .globl do1 .globl do12 .globl do14 .globl do2 .globl do22 .globl do24 .globl goto .globl cgoto .globl cagoto .globl agoto .globl rerr gas8: mov 8.(sp),r0 mov (sp)+,(r0)+ mov (sp)+,(r0)+ br 1f gas1: movb (sp)+,*(sp)+ jmp *(r4)+ gas2: mov (sp)+,*(sp)+ jmp *(r4)+ gas4: mov 4(sp),r0 1: mov (sp)+,(r0)+ mov (sp)+,(r0) tst (sp)+ jmp *(r4)+ stop: sys exit lval: mov (r4)+,-(sp) jmp *(r4)+ rval8: mov (r4)+,r0 add $8.,r0 mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) mov -(r0),-(sp) jmp *(r4)+ rval4: mov (r4)+,r0 mov 2(r0),-(sp) mov (r0),-(sp) jmp *(r4)+ do22: mov (sp)+,r1 br 1f do12: mov $1,r1 1: mov (sp)+,r2 mov (sp)+,r0 add r1,(r0) cmp (r0),r2 bgt goto tst (r4)+ jmp *(r4)+ do24: do2: mov (sp)+,r2 mov (sp)+,r1 br 1f do14: do1: clr r2 mov $1,r1 1: mov 4(sp),r0 add r1,2(r0) adc r2 add r2,(r0) cmp (r0)+,(sp)+ bgt 1f blt 2f cmp (r0),(sp) bhi 1f 2: cmp (sp)+,(sp)+ tst (r4)+ jmp *(r4)+ 1: cmp (sp)+,(sp)+ goto: mov (r4),r4 jmp *(r4)+ cgoto: tst (sp)+ mov (sp)+,r0 asl r0 add r4,r0 1: tst (r4)+ beq gotoe cmp r0,r4 bne 1b mov -(r0),r4 jmp *(r4)+ cagoto: tst (sp)+ mov (sp)+,r0 1: tst (r4) beq gotoe cmp r0,(r4)+ bne 1b mov r0,r4 jmp *(r4)+ agoto: tst (sp)+ mov (sp)+,r4 jmp *(r4)+ gotoe: jsr r5,rerr; 14. 2 mov $1,r1 1: mov 4(sp),r0 add r1,2(r0) adc r2 add r2,(r0) cmp (r0)+,(sp)+ bgt 1f blt 2f cmp (r0),/ / / r2 -- comparison of 4-byte integers .globl ilt4 .globl ile4 .globl ieq4 .globl ine4 .globl ige4 .globl igt4 .globl lan2 .globl lor2 .globl lnt2 .globl ieq2 .globl ile2 .globl igt2 .globl ige2 .globl leq2 .globl ine2 .globl ilt2 .globl lne2 .globl leq1 .globl lne1 ilt4: jsr pc,compar blt one br zero blo one br zero ile4: jsr pc,compar ble one br zero blos one br zero ieq4: jsr pc,compar beq one br zero beq one br zero ine4: jsr pc,compar bne one br zero bne one br zero ige4:  jsr pc,compar bge one br zero bhis one br zero igt4: jsr pc,compar bgt one br zero bhi one br zero one: mov $1,(sp) jmp *(r4)+ zero: clr (sp) jmp *(r4)+ compar: mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 cmp (sp)+,r1 beq 1f jmp (r0) 1: cmp (sp),r2 jmp 4(r0) lor2: bis (sp)+,(sp) jmp *(r4)+ lan2: tst (sp)+ bne 1f clr (sp) 1: jmp *(r4)+ lnt2: tst (sp) beq one br zero ieq2: leq2: cmp (sp)+,(sp) beq one br zero ilt2: cmp (sp)+,(sp) bgt one br zero ile2: cmp (sp)+,(sp) bge one br zero igt2: cmp (sp)+,(sp) blt one br zero ige2: cmp (sp)+,(sp) ble one br zero ine2: lne2: cmp (sp)+,(sp) bne one br zero leq1: cmpb (sp)+,(sp) beq one br zero lne1: cmpb (sp)+,(sp) bne one br zero ,r1 beq 1f jmp (r0) 1: cmp (sp),r2 jmp 4(r0) lor2: bis (sp)+,(sp) jmp *(r4)+ lan2: tst (sp)+ bne 1f clr (sp) 1: jmp *(r4)+ lnt2: tst (sp) beq one br zero ieq2: leq2: cmp (sp)+,(sp) beq one br zero ilt2: cmp (sp)+,(sp) bgt one br zero ile2: cmp (sp)+,(sp) / / / r3 -- comparisons .globl lif2 .globl lif1 .globl rif4 .globl iif2 .globl iif4 .globl rif8 lif2: lif1: tst (sp)+ bne 1f mov (r4),r4 jmp *(r4)+ 1: tst (r4)+ jmp *(r4)+ rif8: setd tstf (sp)+ cfcc br 2f iif4: rif4: mov (sp)+,r0 mov (sp)+,r1 tst r0 bne 2f tst r1 cln br 2f iif2: tst (sp)+ 2: bmi 1f beq 2f tst (r4)+ 2: tst (r4)+ 1: mov (r4),r4 jmp *(r4)+ one br zero ieq2: leq2: cmp (sp)+,(sp) beq one br zero ilt2: cmp (sp)+,(sp) bgt one br zero ile2: cmp (sp)+,(sp) / / / r4 -- short integer arithmetic .globl iad2 .globl isb2 .globl imp2 .globl idv2 .globl i2i4 .globl i1i4 .globl i4i2 .globl i4i1 .globl ing2 .globl rval2 .globl rval1 .globl l2l1 iad2: add (sp)+,(sp) jmp *(r4)+ isb2: sub (sp)+,(sp) jmp *(r4)+ imp2: mov (sp)+,r1 mul (sp)+,r1 mov r1,-(sp) jmp *(r4)+ idv2: mov 2(sp),r1 sxt r0 div (sp)+,r0 mov r0,(sp) jmp *(r4)+ i4i2: i4i1: tst (sp)+ jmp *(r4)+ i1i4: movb (sp),r0 mov r0,(sp) i2i4: tst (sp) sxt -(sp) jmp *(r4)+ ing2: neg (sp) jmp *(r4)+ rval2: mov *(r4)+,-(sp) jmp *(r4)+ rval1: movb *(r4)+,r0 mov r0,-(sp) l2l1: jmp *(r4)+ i1i4 .globl i4i2 .globl i4i1 .globl ing2 .globl rval2 .globl rval1 .globl l2l1 iad2: add (sp)+,(sp) jmp *(r4)+ isb2: sub (sp)+,(sp) jmp *(r4)+ imp2: mov (sp)+,r1 mul (sp)+,r1 mov r1,-(sp) jmp *(r4)+ idv2: mov 2(sp),r1 sxt r0 div (sp)+,r0 mov r0,(sp) jmp *(r4)+ i4i2: i4i1: tst (sp)+ jmp *(r4)+ i1i4: movb (sp),r0 mov r0,(sp) i2i4: tst (sp) sxt -(sp) jmp *(r4)+ ing2: neg (sp) j/ / / r5 -- long integer arithmetic .globl iad4 .globl isb4 .globl imp4 .globl idv4 .globl ing4 .globl rerr iad4: jsr pc,load addf fr0,fr1 br store isb4: jsr pc,load subf fr0,fr1 br store imp4: jsr pc,load mulf fr0,fr1 br store idv4: jsr pc,load divf fr0,fr1 store: movfi fr1,-(sp) jmp *(r4)+ load: mov (sp)+,r0 setd setl movif (sp)+,fr0 movif (sp)+,fr1 jmp (r0) ing4: neg (sp) neg 2(sp) sbc (sp) jmp *(r4)+ mov r0,(sp) i2i4: tst (sp) sxt -(sp) jmp *(r4)+ ing2: neg (sp) j/ / / r6 -- real arithmetic .globl rad4 .globl rad8 .globl rsb4 .globl rsb8 .globl rmp4 .globl rmp8 .globl rdv4 .globl rdv8 .globl rng4 .globl rng8 .globl r4r8 .globl r8r4 .globl i4r4 .globl i2r4 .globl r4i4 .globl r8i2 .globl i2r8 .globl r4i2 .globl i4r8 .globl r8i4 .globl rerr rad8: setd br 1f rad4: setf 1: movf (sp)+,fr0 addf (sp)+,fr0 br store rsb8: setd br 1f rsb4: setf 1: movf (sp)+,fr0 negf fr0 addf (sp)+,fr0 br store rmp8: setd br 1f rmp4: setf 1: movf (sp)+,fr0 mulf (sp)+,fr0 br store rdv8: setd br 1f rdv4: setf 1: movf (sp)+,fr1 movf (sp)+,fr0 divf fr1,fr0 store: movf fr0,-(sp) jmp *(r4)+ rng8: setd br 1f rng4: setf 1: negf (sp) jmp *(r4)+ r8r4: setd br 1f r4r8: setf 1: movf (sp)+,fr0 movfo fr0,-(sp) jmp *(r4)+ i2r8: seti br 1f i4r8: setl 1: setd br 2f i2r4: seti br 1f i4r4: setl 1: setf 2: movif (sp)+,fr0 movf fr0,-(sp) jmp *(r4)+ r8i2: seti br 1f r8i4: setl 1: setd br 2f r4i2: seti br 1f r4i4: setl 1: setf 2: movf (sp)+,fr0 movfi fr0,-(sp) jmp *(r4)+ v4: setf 1: movf (sp)+,fr1 movf (sp)+,fr0 divf fr1,fr0 store: movf fr0,-(sp) jmp *(r4)+ rng8: setd br 1f rng4: setf 1: negf (sp) jmp *(r4)+ r8r4: setd br 1f r4r8: setf 1: movf (sp)+,fr0 movfo fr0,-(sp) jmp *(r4)+ i2r8: seti br 1f i4r8: setl 1: setd br 2f i2r4: seti br 1f i4r4: setl 1: setf 2: movif (sp)+,fr0 movf fr0,-(sp) jmp *(r4)+ r8i2: seti br 1f r8i4: setl 1: setd br 2f r4i2: seti br 1f r4i4: setl 1: setf 2: movf (sp)+,f/ / / r7 -- fortran runtime achk = 1 / 1 to check array bounds .globl lvalp .globl rval1p .globl rval2p .globl rval4p .globl rval8p .globl alval .globl alvalp .globl arval .globl arvalp .globl rerr lvalp: mov r3,r0 add (r4)+,r0 mov (r0)+,-(sp) jmp *(r4)+ rval1p: mov r3,r0 add (r4)+,r0 movb *(r0)+,-(sp) jmp *(r4)+ rval2p: mov r3,r0 add (r4)+,r0 mov *(r0)+,-(sp) jmp *(r4)+ rval4p: mov r3,r0 add (r4)+,r0 mov (r0),r0 cmp (r0)+,(r0)+ mov -(r0),-(sp) mov -(r0),-(sp) jmp *(r4)+ rval8p: setd mov r3,r0 add (r4)+,r0 movf *(r0)+,fr0 movf fr0,-(sp) jmp *(r4)+ alval: jsr r5,getsub; 1 mov (r4)+,-(sp) add r1,(sp) jmp *(r4)+ arvalp: jsr r5,getsub; 0 mov r3,r2 add (r4)+,r2 mov (r2),r2 br 1f arval: jsr r5,getsub; 1 mov (r4)+,r2 1: add r2,r1 mov -(r0),r2 asr r2 bcc 1f movb (r1),-(sp) jmp *(r4)+ 1: add (r0),r1 1: mov -(r1),-(sp) sob r2,1b jmp *(r4)+ getsub: tst (sp)+ mov (r4)+,r0 mov (r0)+,r2 clr r1 tst (r0)+ 1: tst (sp)+ dec (sp) add (sp)+,r1 mpy (r0)+,r1 sob r2,1b tst (r5)+ beq 2f mov r1,-(sp) mov -2(r4),r0 mov (r0)+,r2 inc r2 mov $1,r1 1: mpy (r0)+,r1 sob r2,1b .if achk cmp r1,(sp) bhi 1f jsr r5,rerr; 15. .endif 1: mov (sp)+,r1 2: jmp (r5) alvalp: jsr r5,getsub; 0 mov r3,r0 add (r4)+,r0 mov (r0),-(sp) add r1,(sp) jmp *(r4)+ c 1f movb (r1),-(sp) jmp *(r4)+ 1: add (r0),r1 1: mov -(r1),-(sp) sob r2,1b jmp *(r4)+ getsub: tst (sp)+ mov (r4)+,r0 mov (r0)+,r2 clr r1 tst (r0)+ 1: tst (sp)+ dec (sp) add (sp)+,r1 mpy (r0)+,r1 sob r/ / / r8 - fortran runtime -- powers of integers .globl ipi2 ipi2: tst (sp)+ mov (sp)+,r0 bge 1f clr (sp) jmp *(r4)+ 1: mov (sp)+,r1 mov r3,-(sp) mov $1,r3 1: tst r0 beq 1f asr r0 bcc 2f mpy r1,r3 2: mpy r1,r1 br 1b 1: mov r3,r1 mov (sp)+,r3 mov r1,-(sp) jmp *(r4)+ r4)+ c 1f movb (r1),-(sp) jmp *(r4)+ 1: add (r0),r1 1: mov -(r1),-(sp) sob r2,1b jmp *(r4)+ getsub: tst (sp)+ mov (r4)+,r0 mov (r0)+,r2 clr r1 tst (r0)+ 1: tst (sp)+ dec (sp) add (sp)+,r1 mpy (r0)+,r1 sob r/ / one = 40200 / r9 -- fortran runtime -- real**integer .globl ipi4 .globl rpi4 .globl rpi8 .globl rerr ipi4: setf setl movif 4(sp),fr0 movf fr0,4(sp) jsr r5,1f movfi fr1,-(sp) jmp *(r4)+ rpi4: setf br 2f rpi8: setd 2: jsr r5,1f movf fr1,-(sp) jmp *(r4)+ 1: cmp (sp)+,(sp)+ / jsr + msp of i4 mov (sp)+,r0 movf $one,fr1 movf (sp)+,fr0 tst r0 bgt 1f cfcc beq 9f tst r0 beq 3f divf fr0,fr1 movf fr1,fr0 neg r0 movf $one,fr1 1: asr r0 bcc 2f mulf fr0,fr1 2: tst r0 beq 3f mulf fr0,fr0 br 1b 3: jmp (r5) 9: jsr r5, rerr; 17. ger .globl ipi4 .globl rpi4 .globl rpi8 .globl rerr ipi4: setf setl movif 4(sp),fr0 movf fr0,4(sp) jsr r5,1f movfi fr1,-(sp) jmp *(r4)+ rpi4: setf br 2f rpi8: setd 2: jsr r5,1f movf fr1,-(sp) jmp *(r4)+ 1: cmp (sp)+,(sp)+ / jsr + msp of i4 mov (sp)+,r0 movf $one,fr1 movf (sp)+,fr0 tst r0 bgt 1f cfcc beq 9f tst r0 beq 3f divf fr0,fr1 movf fr1,fr0 neg r0 movf $one,fr1 1: asr r0 bcc 2f mulf fr0,fr1 2: tst r0 beq 3f m/ / / ra -- fortran runtime -- real ** real .globl rpr4 .globl rpr8 .globl log .globl exp .globl rerr rpr8: setd br 1f rpr4: setf 1: seti movf (sp)+,fr1 movf (sp)+,fr0 cfcc beq 3f / 0**x movf fr1,-(sp) jsr pc,log bes error mulf (sp)+,fr0 jsr pc,exp bes error 2: movf fr0,-(sp) jmp *(r4)+ 3: tstf r1 cfcc bgt 2b error: jsr r5,rerr; 17. 0 bgt 1f cfcc beq 9f tst r0 beq 3f divf fr0,fr1 movf fr1,fr0 neg r0 movf $one,fr1 1: asr r0 bcc 2f mulf fr0,fr1 2: tst r0 beq 3f m/ rb -- funct/subr stuff .globl call .globl callp .globl retrn .globl lino .globl entry .globl trace .globl pdec .globl temp .globl stsp .globl ent,lin,disp callp: mov (r4)+,r0 add r3,r0 mov (r0),r0 br 1f call: mov (r4)+,r0 1: mov disp,-(sp) mov lin,-(sp) mov ent,-(sp) mov sp,disp mov r3,-(sp) mov (r4)+,r3 mov r4,-(sp) mov r0,r4 mov (r4)+,-(sp) / lv of funct jmp *(r4)+ retrn: mov r3,r0 mov (sp)+,r1 / lv of funct mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,ent mov (sp)+,lin mov (sp)+,disp mov (r0),sp tst (r4)+ / arg count mov (r4)+,r0 / return byte count inc r0 bic $1,r0 add r0,r1 1: sub $2,r0 blt 1f mov -(r1),-(sp) br 1b 1: jmp *(r4)+ stsp: mov sp,*(r4)+ jmp *(r4)+ lino: mov (r4)+,lin jmp *(r4)+ entry: mov (r4)+,ent jmp *(r4)+ trace: mov (sp)+,r2 1: mov ent,r1 jsr r5,pstr mov $2,r0 sys write; m1; 1 mov lin,r1 jsr r5,pdec mov $2,r0 sys write; m2; 1 tst disp beq 1f mov disp,sp mov (sp)+,ent mov (sp)+,lin mov (sp)+,disp br 1b 1: jmp (r2) pstr: tst r1  bne 1f mov $m3,r1 1: movb (r1)+,temp beq 1f mov $2,r0 sys write; temp; 1 br 1b 1: rts r5 .data m1: < > m2: <\n> m3: <.main.\0> .even .bss disp: .=.+2 lin: .=.+2 ent: .=.+2 r4)+ jmp *(r4)+ lino: mov (r4)+,lin jmp *(r4)+ entry: mov (r4)+,ent jmp *(r4)+ trace: mov (sp)+,r2 1: mov ent,r1 jsr r5,pstr mov $2,r0 sys write; m1; 1 mov lin,r1 jsr r5,pdec mov $2,r0 sys write; m2; 1 tst disp beq 1f mov disp,sp mov (sp)+,ent mov (sp)+,lin mov (sp)+,disp br 1b 1: jmp (r2) pstr: tst r1 / / / rc -- complex arithmetic .globl c8c16 .globl c16c8 .globl i4c8 .globl r4c8 .globl r8c8 .globl i4c16 .globl r4c16 .globl r8c16 .globl cad8 .globl csb8 .globl cmp8 .globl cdv8 .globl cng8 .globl cad16 .globl csb16 .globl cmp16 .globl cdv16 .globl cng16 .globl rval16 .globl rval16p .globl gas16 .globl ceq8 .globl cne8 .globl ceq16 .globl cne16 .globl cpi8 .globl cpi16 one = 040200 a = r2 b = r3 c = r4 d = r5 e = r0 f = r1 gas16: mov 16.(sp),r0 setd movf (sp)+,a movf (sp)+,b tst (sp)+ movf a,(r0)+ movf b,(r0)+ jmp *(r4)+ rval16p: mov r3,r0 add (r4)+,r0 mov (r0),r0 br 1f rval16: mov (r4)+,r0 1: setd movf (r0)+,a movf (r0)+,b movf b,-(sp) movf a,-(sp) jmp *(r4)+ cad16: setd br 1f cad8: setf 1: jsr pc,garg addf a,e addf b,f br sarg csb16: setd br 1f csb8: setf 1: jsr pc,garg subf a,e negf e subf b,f negf f br sarg cmp16: setd br 1f cmp8: setf 1: jsr pc,garg mulf a,e mulf b,f subf f,e mulf d,a mulf c,b movf a,f addf b,f sarg: movf f,-(sp) movf e,-(sp) jmp *(r4)+ cdv16: setd br 1f cdv8: setf 1: divide: jsr pc,garg absf e absf f cmpf e,f cfcc blt 1f / algorithm #1 |c| > |d| movf d,e divf c,e / r = d/c movf d,f mulf e,f addf c,f / x = c+rd movf f,c movf a,f mulf e,f negf f addf b,f mulf b,e addf a,e divf c,e divf c,f br sarg / algorithm #2 |c| < |d| 1: movf c,e divf d,e / r = c/d movf c,f mulf e,f addf d,f / x = d+rc movf f,c movf b,f mulf e,f subf a,f mulf a,e addf b,e divf c,e divf c,f br sarg cng16: setd br 1f cng8: setf 1: movf (sp)+,a negf a negf (sp) movf a,-(sp) jmp *(r4)+ / setup the following registers / (a,bi) +o (c,di) -> (e+fi) / a,b,c,d are input / e,f are output and also contain / c,d on input garg: mov (sp)+,r0 movf (sp)+,e movf e,c movf (sp)+,f movf f,d movf (sp)+,a movf (sp)+,b jmp (r0) i4c8: setf br 1f i4c16: setd 1: setl movif (sp)+,fr0 br 2f r4c8: setf br 1f r8c16: setd 1: movf (sp)+,fr0 br 2f r4c16: setd br 1f r8c8: setf 1: movof (sp)+,fr0 2: clrf -(sp) movf fr0,-(sp) jmp *(r4)+ c16c8: setd br 1f c8c16: setf 1: movf (sp)+,r0 movf (sp)+,r1 movfo r1,-(sp) movfo r0,-(sp) jmp *(r4)+ ceq16: setd br 1f ceq8: setf 1: mov $1,r1 br 2f cne16: setd br 1f cne8: setf 1: clr r1 2: jsr pc,garg cmpf c,a cfcc bne 1f cmpf d,b cfcc beq 2f 1: inc r1 bic $2,r1 2: mov r1,-(sp) jmp *(r4)+ cpi8: setf br 1f cpi16: setd 1: clr r0 tst (sp)+ mov (sp)+,r1 bge 1f inc r0 neg r1 1: movf (sp)+,fr0 movf fr0,fr4 movf (sp)+,fr0 movf fr0,fr5 movf $one,fr0 clrf fr1 1: dec r1 bmi 1f movf fr0,fr2 movf fr1,fr3 mulf fr4,fr0 mulf fr4,fr1 mulf fr5,fr2 mulf fr5,fr3 subf fr3,fr0 addf fr2,fr1 br 1b 1: tst r0 beq 1f clrf -(sp) movf $one,fr2 movf fr2,-(sp) movf fr1,-(sp) movf fr0,-(sp) jmp divide 1: movf fr1,-(sp) movf fr0,-(sp) jmp *(r4)+ bic $2,r1 2: mov r1,-(sp) jmp *(r4)+ cpi8: setf br 1f cpi16: setd 1: clr r0 tst (sp)+ mov (sp)+,r1 bge 1f inc r0 neg r1 1: movf (sp)+,fr0 movf fr0,fr4 movf (sp)+,fr0 movf / / / rd -- short list I/O do loop .globl slist1 .globl slist2 .globl slist3 .globl temp slist1: mov (r4)+,r0 mov (r0)+,r2 mov $1,r1 1: mpy (r0)+,r1 sob r2,1b mov $temp,r2 mov r1,(r2)+ clr (r2)+ mov (r0)+,(r2)+ jmp *(r4)+ slist2: mov (r4)+,r0 dec temp ble 1f mov r0,r4 1: jmp *(r4)+ slist3: mov $temp+2,r0 add (r0)+,(sp) add (r0),-(r0) jmp *(r4)+ tf br 1f cpi16: setd 1: clr r0 tst (sp)+ mov (sp)+,r1 bge 1f inc r0 neg r1 1: movf (sp)+,fr0 movf fr0,fr4 movf (sp)+,fr0 movf / / / re -- comparison of 8-byte quantities .globl rle8 .globl rlt8 .globl req8 .globl rne8 .globl rge8 .globl rgt8 rlt8: jsr pc,compar blt one br zero rle8: jsr pc,compar ble one br zero req8: jsr pc,compar beq one br zero rne8: jsr pc,compar bne one br zero rge8: jsr pc,compar bge one br zero rgt8: jsr pc,compar bgt one br zero one: mov $1,-(sp) jmp *(r4)+ zero: clr -(sp) jmp *(r4)+ compar: setd mov (sp)+,r0 movf (sp)+,fr0 cmpf (sp)+,fr0 cfcc jmp (r0) sp)+,fr0 movf / / / rf -- real comparisons .globl rlt4 .globl rle4 .globl req4 .globl rne4 .globl rge4 .globl rgt4 rlt4: jsr pc,compar blt one br zero rle4: jsr pc,compar ble one br zero req4: jsr pc,compar beq one br zero rne4: jsr pc,compar bne one br zero rge4: jsr pc,compar bge one br zero rgt4: jsr pc,compar bgt one br zero one: mov $1,-(sp) jmp *(r4)+ zero: clr -(sp) jmp *(r4)+ compar: mov (sp)+,r0 setf movf (sp)+,r0 cmpf (sp)+,r0 cfcc jmp (r0) cfcc jmp (r0) sp)+,fr0 movf / / / rg -- assignments .globl gmv1 .globl gmv2 .globl gmv4 .globl gmv8 .globl gmv16 .globl stst gmv1: movb (sp)+,*(r4)+ jmp *(r4)+ gmv2: stst: mov (sp)+,*(r4)+ jmp *(r4)+ gmv4: mov (r4)+,r0 mov (sp)+,(r0)+ mov (sp)+,(r0)+ jmp *(r4)+ gmv8: setd movf (sp)+,fr0 movf fr0,*(r4)+ jmp *(r4)+ gmv16: setd mov (r4)+,r0 movf (sp)+,fr0 movf fr0,(r0)+ movf (sp)+,fr0 movf fr0,(r0)+ jmp *(r4)+ .globl gmv1p .globl gmv2p .globl gmv4p .globl gmv8p .globl gmv16p gmv1p: mov (r4)+,r0 add r3,r0 movb (sp)+,*(r0)+ jmp *(r4)+ gmv2p: mov (r4)+,r0 add r3,r0 mov (sp)+,*(r0)+ jmp *(r4)+ gmv4p: mov (r4)+,r0 add r3,r0 mov (r0),r0 mov (sp)+,(r0)+ mov (sp)+,(r0)+ jmp *(r4)+ gmv8p: setd mov (r4)+,r0 add r3,r0 movf (sp)+,fr0 movf fr0,*(r0)+ jmp *(r4)+ gmv16p: setd mov (r4)+,r0 add r3,r0 mov (r0),r0 movf (sp)+,fr0 movf fr0,(r0)+ movf (sp)+,fr0 movf fr0,(r0)+ jmp *(r4)+ jmp *(r4)+ .globl gmv1p .globl gmv2p .globl gmv4p .globl gmv8p .globl gmv16p gmv1p: mov (r4)+,r0 add r3,r0 mo/ / / rh -- simple array l/r values achk = 1 / 1 to check array bounds .globl gal1 .globl gal2 .globl gal4 .globl gal8 .globl gal16 .globl gar1 .globl gar2 .globl gar4 .globl gar8 .globl gar16 .globl rerr gal1: tst (sp)+ dec (sp) br 1f gal2: tst (sp)+ dec (sp) asl (sp) br 1f gal4: tst (sp)+ dec (sp) asl (sp) asl (sp) br 1f gal8: tst (sp)+ dec (sp) asl (sp) asl (sp) asl (sp) br 1f gal16: tst (sp)+ dec (sp) asl (sp) asl (sp) asl (sp) asl (sp) 1: cmp (sp),(r4)+ .if achk bhis 9f .endif add (r4)+,(sp) jmp *(r4)+ 9: jsr r5,rerr; 15. 4 gar1: tst (sp)+ dec (sp) cmp (sp),(r4)+ .if achk bhis 9b .endif add (r4)+,(sp) movb *(sp)+,r0 mov r0,-(sp) jmp *(r4)+ gar2: tst (sp)+ dec (sp) asl (sp) cmp (sp),(r4)+ .if achk bhis 9b .endif add (r4)+,(sp) mov *(sp)+,-(sp) jmp *(r4)+ gar4: tst (sp)+ dec (sp) mov (sp)+,r0 asl r0 asl r0 cmp r0,(r4)+ .if achk bhis 9b .endif add (r4)+,r0 cmp (r0)+,(r0)+ mov -(r0),-(sp) mov -(r0),-(sp) jmp *(r4)+ gar8: setd tst (sp)+ dec (sp) asl (sp) asl (sp) asl (sp) cmp (sp),(r4)+ .if achk bhis 9b .endif add (r4)+,(sp) movf *(sp)+,fr0 movf fr0,-(sp) jmp *(r4)+ gar16: setd tst (sp)+ dec (sp) mov (sp)+,r0 asl r0 asl r0 asl r0 asl r0 cmp r0,(r4)+ .if achk bhis 9b .endif add (r4)+,r0 movf (r0)+,fr0 movf (r0)+,fr1 movf fr1,-(sp) movf fr0,-(sp) jmp *(r4)+ r0 asl r0 asl r0 cmp r0,(r4)+ .if achk bhis 9b .endif add (r4)+,r0 cmp (r0)+,(r0)+ mov -(r0),-(sp) mov -(r0),-(sp) jmp *(r4)+ gar8: setd tst (sp)+/ / / rtx -- last routine .globl ecore .bss ecore: .if achk bhis 9b .endif add (r4)+,(sp) movf *(sp)+,fr0 movf fr0,-(sp) jmp *(r4)+ gar16: setd tst (sp)+ dec (sp) mov (sp)+,r0 asl r0 asl r0 asl r0 asl r0 cmp r0,(r4)+ .if achk bhis 9b .endif add (r4)+,r0 movf (r0)+,fr0 movf (r0)+,fr1 movf fr1,-(sp) movf fr0,-(sp) jmp *(r4)+ r0 asl r0 asl r0 cmp r0,(r4)+ .if achk bhis 9b .endif add (r4)+,r0 cmp (r0)+,(r0)+ mov -(r0),-(sp) mov -(r0),-(sp) jmp *(r4)+ gar8: setd tst (sp)+/ / / fhd -- data segment header / .fc = 1 .if .fc-2 / fc1 sizes symsize = 1600. linsize = 800. namsize = 1200. smblsize = 399. .endif .if .fc-1 / fc2 sizes symsize = 1600. linsize = 1300. namsize = 1200. smblsize = 399. .endif intcon = 4\<8+1 / type of integer constant realcon = 4\<8+2 logcon = 2\<8+3 / type of logical constant / 4 bytes to be ASA log1con = 1\<8+3 int1con = 1\<8+1 int2con = 2\<8+1 dblcon = 10\<8+2 dcplxcon = 20\<8+4 cplxcon = 10\<8+4 undefcon = 2\<8+6 .globl data .globl ibuf .globl obuf .globl tbuf .globl line .globl eline .globl ifno .globl efno .globl errp .globl errb .globl eerrb .globl symtab .globl esymtab .globl esymp .globl symtp .globl namebuf .globl enamebuf .globl namep .globl symbuf .globl esymbuf .globl ch .globl ch1 .globl progt .globl holquo .globl nxtaloc .globl imptab .globl nerror .globl temp .globl functm .globl edata .globl dsize n = 1\<8+1 int2con = 2\<8+1 dblcon = 10\<8+2 dcplxcon = 20\<8+4 cplxcon = 10\<8+4 undefcon = 2\<8+6 .globl / / / fx1 -- utility .globl lookup / lookup / lookup string pointed at by r2 / in table pointed at by arg1 / r0 returns symbol number*2 / r2 is advanced by matched string / registers used: r0,r2 lookup: mov r1,-(sp) clr r0 mov r2,-(sp) mov (r5)+,r1 1: mov (sp),r2 tstb (r1) beq 1f 2: cmpb (r2)+,(r1)+ bne 2f tstb (r1) bne 2b asl r0 cmp (r5)+,(sp)+ mov (sp)+,r1 rts r5 2: tstb (r1)+ bne 2b inc r0 br 1b 1: mov (sp)+,r2 mov (sp)+,r1 rts r5 +4 cplxcon = 10\<8+4 undefcon = 2\<8+6 .globl / / / fx2 -- error setting and printing .globl error .globl perror .globl tput .globl tdecml error: inc nerror mov r0,-(sp) mov r2,-(sp) mov (r5)+,r0 mov $errb,r2 1: cmp r2,errp bhis 1f cmp r0,(r2)+ beq 2f tst (r2)+ br 1b 1: cmp r2,$eerrb bhis 2f mov r0,(r2)+ mov r1,(r2) dec (r2)+ / r1 is often 1 too far mov r2,errp 2: mov (sp)+,r2 mov (sp)+,r0 rts r5 perror: cmp errp,$errb beq 1f mov r1,-(sp) mov r2,-(sp) mov ifno,r0 jsr r5,tdecml mov $'\t,r0 jsr r5,tput mov $line,r1 2: movb (r1),r0 beq 2f jsr r5,tput mov $errb+2,r2 3: cmp r1,(r2)+ bne 4f mov $1,r0 sys write; mes2; 2 / bs, _ br 3f 4: cmp r2,errp blo 3b 3: inc r1 br 2b 2: mov $errb,r1 2: mov $1,r0 sys write; mes1; 4 3: sys open; errfil; 0 bec 3f mov (r1)+,r0 tst (r1)+ jsr r5,tdecml cmp r1,errp bhis 2f mov $',,r0 jsr r5,tput br 3b 3: mov r0,-(sp) mov (r1)+,r2 tst (r1)+ 3: dec r2 ble 3f 4: mov (sp),r0 sys read; ich; 1 bes 4f tst r0 beq 4f cmpb ich,$'\n bne 4b br 3b 3: mov (sp),r0 sys read; ich; 1 bes 4f tst r0 beq 4f movb ich,r0 cmp r0,$'\n beq 3f jsr r5,tput br 3b 4: mov $1,r0 sys write; mes3; 18. 3: mov (sp)+,r0 sys close cmp r1,$errp blo 2b 2: mov $'\n,r0 jsr r5,tput mov $errb,errp mov (sp)+,r2 mov (sp)+,r1 1: rts r5 mes1: <\n** > mes2: .byte 010, '_ mes3: errfil: .even .bss ich: .=.+2 (r1)+ 3: dec r2 ble 3f 4: mov (sp),r0 sys read; ich; 1 bes 4f tst r0 beq 4f cmpb ich,$'\n bne 4b br 3b 3: mov (sp),r0 sys re/ / / fx3 -- get integer .globl geti .globl ptemp .globl putc .globl putw geti: mov r1,-(sp) mov r3,-(sp) clr r3 mov $symbuf,r0 1: movb (r0)+,r1 sub $'0,r1 cmp r1,$9 bhi 1f mpy $10.,r3 add r1,r3 br 1b 1: mov r3,r0 mov (sp)+,r3 mov (sp)+,r1 rts r5 ptemp: mov r0,-(sp) mov r1,-(sp) mov (r5)+,r0 / character jsr r5,putc; tbuf mov *(r5)+,r0 / word jsr r5,putw; tbuf mov ifno,r0 jsr r5,putw; tbuf mov (r5)+,r1 / string 1: movb (r1),r0 jsr r5,putc; tbuf tstb (r1)+ bne 1b mov (sp)+,r1 mov (sp)+,r0 rts r5 .globl geti .globl ptemp .globl putc .globl putw geti: mov r1,-(sp) mov r3,-(sp) clr r3 mov $symbuf,r0 1: movb (r0)+,r1 sub $'0,r1 cmp r1,$9 bhi 1f mpy $10.,r3 add r1,r3 br 1b 1: mov r3,r0 mov (sp)+,r3 mov (sp)+,r1 rts r5 ptemp: mov r0,-(sp) mov r1,-(sp) mov (r5)+,r0 / character jsr r5,putc; tbuf mov *(r5)+,r0 / word jsr r5,putw; tbuf mov ifno,r0 jsr r5,putw; tbuf mov (r5)+,r1 / string 1: movb (r1),r0 jsr r5,putc; tbuf tstb (r1)+ bne 1b mov (sp)+/ / / fx4 -- get symbol .globl getsym .globl getid .globl lookid .globl chrtab .globl lookup .globl error .globl geti .globl holround / getsym returns the next basic symbol / 0 name (symbol table entry in r3) / 2 number (type in r3) / 4 ** / 6 / / 8 * / 10 - / 12 + / 14 .lt. / 16 .le. / 18 .eq. / 20 .ne. / 22 .gt. / 24 .ge. / 26 .not. / 28 .and. / 30 .or. / 32 ( / 34 ) / 36 , / 38 = / 40 =| / getsym: mov r2,-(sp) mov r1,r2 jsr r5,lookup; bastab br 1f mov r2,r1 cmp r0,$4 bhis 2f asr r0 add $'0,r0 movb r0,symbuf movb $12,symbuf+1 clrb symbuf+2 mov $logcon,r3 / logical*2 mov $2,r0 2: cmp r0,$32. bne 2f / check for possible complex constant mov r1,-(sp) movb -2(r1),r0 movb chrtab(r0),r0 beq 4f cmp r0,$4 blos 3f 4: jsr r5,srconst br 3f mov r3,r2 cmpb (r1)+,$', bne 3f jsr r5,srconst br 3f cmp r3,r2 bhis 4f mov r2,r3 4: cmpb (r1)+,$') bne 3f mov (sp)+,r1 mov $symbuf,r2 4: movb (r1)+,(r2) cmpb (r2)+,$') bne 4b clrb -(r2) mov $2,r0 br 2f 3: mov (sp)+,r1 mov $32.,r0 2: mov (sp)+,r2 rts r5 1: clr lstchr cmp r1,$line blos 1f movb -1(r1),lstchr 1: mov $symbuf,r2 movb (r1)+,r0 movb r0,(r2)+ bic $!177,r0 movb chrtab(r0),r0 jmp *1f(r0) 1: eos let num per eos: mov $40.,r0 tstb -(r1) beq 2b jsr r5,error; 8. br 2b let: dec r1 jsr r5,getid br .+2 / cannot happen jsr r5,lookid; symbuf mov (sp)+,r2 clr r0 rts r5 num: mov $intcon,r3 / integer*4 jsr r5,numst cmpb (r1),$'. bne 2f mov r2,-(sp) mov r1,r2 jsr r5,lookup; bastab br 1f mov (sp)+,r2 br 3f 1: mov (sp)+,r2 movb (r1)+,(r2)+ br 1f 2: cmpb (r1),$'h / hollerith const? bne 2f mov lstchr,r0 cmpb chrtab(r0),$2 / letter? beq 2f / not h, then cmp r0,$'* beq 2f / e.g. real*4 h... clrb (r2) jsr r5,geti mov $symbuf,r2 inc r1 mov holround,-(sp) dec (sp) clr -(sp) 4: movb (r1)+,(r2)+ bne 5f jsr r5,error; 55. br 6f 5: inc (sp) dec r0 bgt 4b 6: bit (sp),2(sp) beq 6f movb $' ,(r2)+ inc (sp) br 6b 6: mov (sp)+,r3 tst (sp)+ swab r3 clrb r3 bis $5,r3 mov $2,r0 mov (sp)+,r2 rts r5 .bss lstchr: .=.+2 .text per: jsr r5,isnum br eos 1: mov $realcon,r3 / real*4 jsr r5,numst 2: jsr r5,expon 3: clrb (r2) mov $2,r0 mov (sp)+,r2 rts r5 isnum: movb (r1),r0 cmpb chrtab(r0),$4 bne 1f tst (r5)+ 1: rts r5 numst: jsr r5,isnum br 1b inc r1 movb r0,(r2)+ br numst expon: cmpb (r1)+,$'e beq 1f cmpb -1(r1),$'d beq 1f 2: dec r1 rts r5 1: cmpb (r1),$'+ beq 1f cmpb (r1),$'- beq 1f jsr r5,isnum br 2b 1: mov $realcon,r3 / real*4 cmpb -(r1),$'e beq 1f mov $dblcon,r3 / real*8 1: movb (r1)+,(r2)+ movb (r1)+,(r2)+ jsr r5,numst rts r5 getid: mov r0,-(sp) mov r2,-(sp) movb (r1),r0 cmpb chrtab(r0),$2 bne 3f tst (r5)+ mov $symbuf,r2 1: movb (r1)+,r0 movb r0,(r2)+ movb chrtab(r0),r0 cmp r0,$2 beq 1b cmp r0,$4 beq 1b dec r1 clrb (r2) movb $12,-(r2) 3: mov (sp)+,r2 mov (sp)+,r0 rts r5 lookid: mov r0,-(sp) mov r2,-(sp) 2: mov (r5),r2 jsr r5,lookup; namebuf br 1f asl r0 asl r0 mov r0,r3 mov (sp)+,r2 mov (sp)+,r0 tst (r5)+ rts r5 1: mov namep,r0 add $8.,symtp 1: movb (r2)+,(r0)+ bne 1b mov r0,namep cmp r0,$enamebuf bhis 1f mov symtp,r0 add $symtab,r0 cmp r0,esymp blo 2b 1: mov $1,r0 sys write; ovfl; eovfl-ovfl clr r0 sys seek; 0; 2 mov $-1,r0 sys exit ovfl: eovfl: .even srconst: cmpb (r1)+,$'+ beq 1f cmpb -(r1),$'- bne 1f inc r1 1: jsr r5,getsym cmp r0,$2 bne 1f clrb r3 add r3,r3 bisb $cplxcon,r3 tst (r5)+ 1: rts r5 chrtab: .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,6,0 .byte 4,4,4,4,4,4,4,4 .byte 4,4,0,0,0,0,0,0 .byte 0,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,0,0,0,0,0 .byte 0,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,0,0,0,0,0 bastab: <.false.\0> <.true.\0> <**\0> <*\0> <-\0> <+\0> <.lt.\0> <.le.\0> <.eq.\0> <.ne.\0> <.gt.\0> <.ge.\0> <.not.\0> <.and.\0> <.or.\0> <(\0> <)\0> <,\0> <=\0> <\0> 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,0,0 .byte 0,0,0,0,0,0,6,0 .byte 4,4,4,4,4,4,4,4 .byte 4,4,0,0,0,0,0,0 .byte 0,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,0,0,0,0,0 .byte 0,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,2,2,2,2,2 .byte 2,2,2,0,0,0,0,0 bastab: <.false.\0> <.true.\0> <**\0> <*\0> <-\0> <+\0> <.lt.\0> <.le.\0> <.eq.\0> <.ne.\0> <.gt.\0> <.ge.\0> <.not.\0> <.and.\0> <.or.\0> <(\0> <)\0> <,\0> </ / / fx5 -- declare implicit .globl declimpl .globl getname declimpl: bit $7,symtab(r3) bne 1f / already declared jsr r5,getname movb symbuf,r0 cmp r0,$'a blo 2f sub $6,r0 / map 'a -> 'Z+1 2: asl r0 bis imptab-[2*'A](r0),symtab(r3) 1: bit $70,symtab(r3) / class bne 1f bis $10,symtab(r3) / simple 1: rts r5 getname: mov r3,-(sp) clr r3 mov $namebuf,r0 1: cmp r3,(sp) bhis 1f 2: tstb (r0)+ bne 2b add $8,r3 br 1b 1: mov $symbuf,r3 2: movb (r0)+,(r3)+ bne 2b mov (sp)+,r3 rts r5 / / fx5 -- declare implicit .globl declimpl .globl getname declimpl: bit $7,symtab(r3) bne 1f / already declared jsr r5,getname movb symbuf,r0 cmp r0,$'a blo 2f sub $6,r0 / map 'a -> 'Z+1 2: asl r0 bis imptab-[2*'A](r0),symtab(r3) 1: bit $70,symtab(r3) / class bne 1f bis $10,symtab(r3) / simple 1: rts r5 getname: mov r3,-(sp) clr r3 mov $namebuf,r0 1: cmp r3,(sp) bhis 1f 2: tstb (r0)+ bne 2b add $8,r3 br 1b 1: mov $symbuf,r3 2: movb (r0)+,(r3)+ bne 2b mov (sp)+,r3 rts r5/ / / fx6 -- teletype .globl tput .globl tdecml tdecml: mov r1,-(sp) jsr r5,td mov (sp)+,r1 rts r5 td: mov r0,r1 clr r0 dvd $10.,r0 mov r1,-(sp) tst r0 beq 1f jsr r5,td 1: mov (sp)+,r0 add $'0,r0 tput: movb r0,ch+1 mov $1,r0 sys write; ch+1; 1 rts r5 class bne 1f bis $10,symtab(r3) / simple 1: rts r5 getname: mov r3,-(sp) clr r3 mov $namebuf,r0 1: cmp r3,(sp) bhis 1f 2: tstb (r0)+ bne 2b add $8,r3 br 1b 1: mov $symbuf,r3 2: movb (r0)+,(r3)+ bne 2b mov (sp)+,r3 rts r5/ / / fx7 -- passes advancement .globl signon .globl signoff .globl pass2 .globl pass3 .globl pass4 signon: tst (r5)+ rts r5 signoff: mov (r5)+,r0 tst (sp)+ dec r0 asl r0 jmp *passtab(r0) passtab: pass2 pass3 pass4 .data 0 sys write; ch+1; 1 rts r5 class bne 1f bis $10,symtab(r3) / simple 1: rts r5 getname: mov r3,-(sp) clr r3 mov $namebuf,r0 1: cmp r3,(sp) bhis 1f 2: tstb (r0)+ bne 2b add $8,r3 br 1b 1: mov $symbuf,r3 2: movb (r0)+,(r3)+ bne 2b mov (sp)+,r3 rts r5/ / / fx8 -- read source line .globl getline .globl isagn .globl levzer .globl error .globl getc .globl chrtab getline: mov r3,-(sp) clr holquo clr r3 / line number clr line mov $line,r1 1: jsr pc,get sub $'0,r0 cmp r0,$9 bhi 1f mpy $10.,r3 add r0,r3 br 1b 1: add $'0,r0 movb r0,ch mov r3,efno 1: mov lino, ifno inc ifno jsr pc,get cmp r0,$'\n / nl beq 1f cmp r0,$'' beq 2f cmp r0,$'" bne 3f 2: mov r0,holquo add $4,r1 / room for h count mov r1,-(sp) 2: jsr pc,get cmp r0,$'\n beq 4f cmp r0,holquo beq 2f bis $200,r0 movb r0,(r1)+ cmp r1,$eline-1 blo 2b 4: tst (sp)+ br err1 2: mov (sp)+,r3 mov r1,-(sp) sub r3,r1 movb $'h,-(r3) clr r0 div $10.,r0 add $'0,r1 movb r1,-(r3) mov r0,r1 clr r0 div $10.,r0 add $'0,r1 movb r1,-(r3) add $'0,r0 movb r0,-(r3) mov (sp)+,r1 clr holquo br 1b 3: cmp r0,$'h bne 2f clr r3 / quote count mov r1,-(sp) 3: cmp r1,$line blos 4f movb -(r1),r0 cmpb chrtab(r0),$4 / digit? beq 3b cmpb chrtab(r0),$2 / test letter beq 3f cmp r0,$'* beq 3f inc r1 4: cmp r1,(sp) bhis 4f movb (r1)+,r0 sub $'0,r0 mpy $10.,r3 add r0,r3 br 4b 4: mov r3,r0 beq 3f mov r0,holquo mov (sp)+,r1 movb $'h,(r1)+ 4: jsr pc,get cmp r0,$'\n bne 5f mov r0,ch mov $' ,r0 5: bis $200,r0 movb r0,(r1)+ cmp r1,$eline-1 bhis err1 dec holquo bne 4b br 1b 3: mov (sp)+,r1 mov $'h,r0 2: movb r0,(r1)+ cmp r1,$eline-1 blo 1b err1: jsr r5,error; 1. 1: clrb (r1)+ mov (sp)+,r3 tstb line bne 1f jmp getline 1: rts r5 isagn: jsr r5,levzer; '= br 1f br 3f 1: mov r0,-(sp) jsr r5,levzer; ', br 4f jsr r5,levzer; '( br 1f tst (sp)+ 2: rts r5 1: cmp (sp)+,r0 blt 2b mov r1,-(sp) mov r0,r1 inc r1 jsr r5,levzer; ') br 1f 1: mov (sp)+,r1 cmpb 1(r0),$'= bne 3f rts r5 levzer: mov r1,r0 clr -(sp) 1: tst (sp) bne 2f cmpb (r0),(r5) beq 1f 2: cmpb (r0),$'( bne 2f inc (sp) 2: cmpb (r0),$') bne 2f dec (sp) blt 5f 2: tstb (r0)+ bne 1b 5: tst (r5)+ 1: 4: tst (sp)+ 3: tst (r5)+ rts r5 get: movb ch,r0 beq 1f clrb ch rts pc 1: jsr pc,get1 cmp r0,$'\n bne 2f jsr pc,get1 cmp r0,$'& beq 1b movb r0,ch1 mov $'\n,r0 2: tst holquo bne 1f cmp $' ,r0 beq 1b cmp $'\t,r0 beq 1b 1: cmp r0,$4 / test EOT bne 1f mov $1,r0 sys write; mes; emes-mes mov $1,r0 / syntax errors detected sys exit 1: rts pc get1: movb ch1,r0 beq 1f clrb ch1 br 2f 1: jsr r5,getc; ibuf bcs 1f bic $!177,r0 beq 1b cmp r0,$'\n bne 2f inc lino 2: tst nlflg beq 2f clr nlflg cmp r0,$'c bne 2f 3: jsr pc,get1 cmp r0,$'\n beq 1b cmp r0,$4 bne 3b 2: cmp r0,$'\n bne 2f inc nlflg 2: rts pc 1: mov $4,r0 rts pc .data nlflg: 1 .text mes: emes: .bss lino: .=.+2 beq 1b 1: cmp r0,$4 / test EOT bne 1f mov $1,r0 sys write; mes; emes-mes mov $1,r0 / syntax errors detected sys exit 1: rts pc get1: movb ch1,r0 beq 1f clrb ch1 br 2f 1: jsr r5,getc; ibuf bcs 1f bic $!177,r0 beq 1b cmp r0,$'\n bne 2f inc lino 2: tst nlflg beq 2f clr nlflg cmp r0,$'c bne 2f 3: jsr pc,get1 cmp r0,$'\n / / / fx9 -- code / jsr r5,code; ; .even / arg1 / arg2 / ... / / args specified by % in string. / %s: string / %d: decimal number / %o: octal number / %c: character / / args are addresses / or registers r0-r4 .globl code .globl putc .globl getname code: mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) mov r1,-(sp) mov r0,-(sp) mov r5,r4 1: tstb (r5)+ bne 1b inc r5 bic $1,r5 1: movb (r4)+,r0 beq 1f cmp r0,$'% beq 2f jsr r5,putc; obuf br 1b 2: movb (r4)+,r0 beq 1f cmp r0,$'s beq cstr cmp r0,$'c beq cchr cmp r0,$'d beq cdec cmp r0,$'o beq coct cmp r0,$'n beq cnam jsr r5,putc; obuf br 1b cnam: jsr pc,cget mov r1,r3 jsr r5,getname mov $symbuf,r1 br 2f cstr: jsr pc,cget 2: movb (r1)+,r0 beq 1b cmp r0,$'\n beq 2b jsr r5,putc; obuf br 2b cchr: jsr pc,cget mov r1,r0 jsr r5,putc; obuf mov r1,r0 clrb r0 swab r0 beq 1b jsr r5,putc; obuf br 1b coct: jsr pc,cget mov $8.,r2 br 2f cdec: jsr pc,cget mov $10.,r2 2: jsr pc,2f br 1b 2: clr r0 dvd r2,r0 mov r1,-(sp) mov r0,r1 beq 2f jsr pc,2b 2: mov (sp)+,r0 add $'0,r0 jsr r5,putc; obuf rts pc 1: mov (sp)+,r0 mov (sp)+,r1 mov (sp)+,r2 mov (sp)+,r3 mov (sp)+,r4 rts r5 cget: mov (r5)+,r1 cmp r1,$4 blos 1f rts pc 1: asl r1 add $2,r1 add sp,r1 mov (r1),r1 rts pc b cchr: jsr pc,cget mov r1,r0 jsr r5,putc; obuf mov r1,r0 clrb r0 swab r0 beq 1b jsr r5,putc; obuf br 1b coct: jsr pc,cget mov $8.,r2 br 2f cdec: jsr pc,cget mov $10.,r2 2: jsr pc,2f br 1b 2: clr r0 dvd / / / fxa -- genop -- output a typed operator .globl genop .globl newline .globl code .globl typ .globl error genop: mov r1,-(sp) mov r3,-(sp) bic $!7,r3 movb typ(r3),r1 cmpb r1,$'u bne 1f jsr r5,error; 34. 1: mov (sp),r3 clrb r3 swab r3 jsr r5,code < %c%c%d\0>; .even r1 r0 r3 mov (sp)+,r3 mov (sp)+,r1 rts r5 newline: jsr r5,code <\n\0>; .even rts r5 typ: coct: jsr pc,cget mov $8.,r2 br 2f cdec: jsr pc,cget mov $10.,r2 2: jsr pc,2f br 1b 2: clr r0 dvd / / / fxb -- get integer constant or label .globl geticon .globl getlab .globl getsym .globl geti .globl ptemp geticon: jsr r5,getsym cmp r0,$2 bne 1f cmp r3,$intcon bne 1f jsr r5,geti tst (r5)+ 1: rts r5 getlab: jsr r5,geticon br 1f mov r0,temp jsr r5,ptemp; 'r; temp; line tst (r5)+ 1: rts r5 mov (sp)+,r1 rts r5 newline: jsr r5,code <\n\0>; .even rts r5 typ: coct: jsr pc,cget mov $8.,r2 br 2f cdec: jsr pc,cget mov $10.,r2 2: jsr pc,2f br 1b 2: clr r0 dvd / / / fxc -- size of array .globl size .globl nelem .globl error size: movb symtab+1(r3),r0 jsr r5,nelem inc r0 bic $1,r0 / round to 0 mod 2 rts r5 nelem: mov r1,-(sp) mov r0,r1 mov symtab(r3),r0 bic $!70,r0 cmp r0,$20 bne 1f mov symtab+2(r3),r0 mov (r0)+,-(sp) 2: mpy (r0)+,r1 dec (sp) bgt 2b tst (sp)+ 1: mov r1,r0 mov (sp)+,r1 rts r5 \n\0>; .even rts r5 typ: coct: jsr pc,cget mov $8.,r2 br 2f cdec: jsr pc,cget mov $10.,r2 2: jsr pc,2f br 1b 2: clr r0 dvd / / / xd -- tmp file 2 handl .globl setln .globl getln .globl tfil2 .globl tfildiag .globl fopen .globl getc .globl getw .globl xbuf setln: mov $tfil2,r0 jsr r5,fopen; xbuf bcc 1f jmp tfildiag 1: rts r5 getln: jsr r5,getc; xbuf bcs 3f mov r0,-(sp) jsr r5,getw; xbuf mov r0,efno jsr r5, getw; xbuf mov r0,ifno mov $line,r1 1: jsr r5,getc; xbuf bcs 1f tst r0 beq 1f bic $200,r0 movb r0,(r1)+ br 1b 1: clrb (r1)+ mov (sp)+,r0 tst (r5)+ rts r5 3: mov xbuf,r0 sys close rts r5 0 dvd / / / xe -- temp file junk .globl tfildiag .globl tfil1, tfil2 tfildiag: mov $1,r0 sys write; mes1; emes1-mes1 clr r0 sys seek; 0; 2 mov $-1,r0 / failure return sys exit mes1: emes1: tfil1: tfil2: ov r0,-(sp) jsr r5,getw; xbuf mov r0,efno jsr r5, getw; xbuf mov r0,ifno mov $line,r1 1: jsr r5,getc; xbuf bcs 1f tst r0 beq 1f bic $200,r0 movb r0,(r1)+ br 1b 1: clrb (r1)+ mov (sp)+,r0 tst (r5)+ rts r5 3: mov xbuf,r0 sys close rts r5 0 dvd / / / fxf -- format statements .globl sform .globl sdata .globl ptemp .globl error sform: cmp progt,$6 / block data bne 1f jsr r5,error; 50. 1: jsr r5,ptemp; 'f; efno; line rts r5 sdata: jsr r5,ptemp; 'd; efno; line rts r5 ov r0,-(sp) jsr r5,getw; xbuf mov r0,efno jsr r5, getw; xbuf mov r0,ifno mov $line,r1 1: jsr r5,getc; xbuf bcs 1f tst r0 beq 1f bic $200,r0 movb r0,(r1)+ br 1b 1: clrb (r1)+ mov (sp)+,r0 tst (r5)+ rts r5 3: mov xbuf,r0 sys close rts r5 0 dvd / / / fxg -- declare implicit functions .globl funimpl .globl getname .globl lookup funimpl: bit $7,symtab(r3) bne 1f jsr r5,getname mov r2,-(sp) mov $symbuf,r2 jsr r5,lookup; funtab br 2f cmpb (r2),$'\n bne 2f asr r0 movb funtabt(r0),r0 mov r0,-(sp) bic $!17,r0 bis typtab(r0),symtab(r3) mov (sp)+,r0 asr r0 asr r0 asr r0 asr r0 bic $!17,r0 mov typtab(r0),symtab+2(r3) / save argument conversion 2: / in dimension pointer mov (sp)+,r2 1: rts r5 typtab: intcon realcon dblcon  cplxcon dcplxcon funtab: <\0> / function type xy / x = arg types / y = result type / 0 = integer / 2 = real / 4 = double / 6 = complex / 8 = doublecomplex funtabt: .byte 2\<4+2 / tanh .byte 2\<4+2 / sqrt .byte 4\<4+2 / sngl .byte 2\<4+2 / sin .byte 2\<4+2 / sign .byte 6\<4+2 / real .byte 0\<4+0 / mod .byte 2\<4+0 / min1 .byte 0\<4+0 / min0 .byte 2\<4+0 / max1 .byte 0\<4+0 / max0 .byte 0\<4+0 / isign .byte 2\<4+0 / int .byte 2\<4+0 / ifix .byte 4\<4+0 / idint .byte 0\<4+0 / idim .byte 0\<4+0 / iabs .byte 0\<4+2 / float .byte 2\<4+2 / exp .byte 4\<4+4 / dsqrt .byte 4\<4+4 / dsin .byte 4\<4+4 / dsign .byte 8\<4+4 / dreal .byte 4\<4+4 / dmod .byte 4\<4+4 / dmin1 .byte 4\<4+4 / dmax1 .byte 4\<4+4 / dlog10 .byte 4\<4+4 / dlog .byte 8\<4+4 / dimag .byte 2\<4+2 / dim .byte 4\<4+4 / dexp  .byte 8\<4+8 / dcsqrt .byte 8\<4+8 / dcsin .byte 4\<4+4 / dcos .byte 8\<4+8 / dconjg .byte 4\<4+8 / dcmplx .byte 8\<4+8 / dclog .byte 8\<4+8 / dcexp .byte 8\<4+8 / dccos .byte 8\<4+4 / dcabs .byte 2\<4+4 / dble .byte 4\<4+4 / datan2 .byte 4\<4+4 / datan .byte 4\<4+4 / dabs .byte 6\<4+6 / csqrt .byte 6\<4+6 / csin .byte 2\<4+2 / cos .byte 6\<4+6 / conjg .byte 2\<4+6 / cmplx .byte 6\<4+6 / clog .byte 6\<4+6 / cexp .byte 6\<4+6 / ccos .byte 6\<4+2 / cabs .byte 2\<4+2 / atan2 .byte 2\<4+2 / atan .byte 2\<4+2 / amod .byte 2\<4+2 / amin1 .byte 0\<4+2 / amin0 .byte 2\<4+2 / amax1 .byte 0\<4+2 / amax0 .byte 2\<4+2 / alog10 .byte 2\<4+2 / alog .byte 2\<4+2 / aint .byte 6\<4+2 / aimag .byte 2\<4+2 / abs te 4\<4+4 / datan .byte 4\<4+4 / dabs .byte 6\<4+6 / csqrt .byte 6\<4+6 / csin .byte 2\<4+2 / cos .byte 6\<4+6 / conjg .byte 2\<4+6 / cmplx .byte 6\<4+6 / clog .byte 6\<4+6 / cexp .byte 6\<4+6 / ccos .byte 6\<4+2 / cabs .byte 2\<4+/ / / fxh -- array constant offset .globl consub .globl getsym .globl geti .globl error .globl geticon / turn constant subscripts into offset. / in: r3 -> symtab / r1 -> just beyond ( / out:r0 has offset consub: mov symtab(r3),r0 bic $!70,r0 cmp r0,$20 / test class == array beq 1f jsr r5,error; 17. clr r0 rts r5 1: mov r5,-(sp) mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) clr r4 / accumulated offset mov symtab+2(r3),r2 / ptr to declarator mov (r2)+,-(sp) / dimensionality mov $1,r5 / prod of declarators 1: jsr r5,geticon br 9f cmp r0,(r2) bgt 3f dec r0 bge 2f 3: jsr r5,error; 19. / out of range clr r0 2: mov r5,-(sp) mpy r0,r5 add r5,r4 mov (sp)+,r5 mpy (r2)+,r5 jsr r5,getsym cmp r0,$36. / comma bne 1f dec (sp) bgt 1b jsr r5,error; 18. / wrong subscript count br 1b 1: cmp r0,$34. / ) beq 1f 9: jsr r5,error; 20. clr r0 1: cmp (sp)+,$1 beq 1f jsr r5,error; 18. / subscript count 1: mov (sp)+,r2 mov (sp)+,r3 movb symtab+1(r3),r5 mpy r4,r5 mov r5,r0 mov (sp)+,r4 mov (sp)+,r5 rts r5 ,geticon br 9f cmp r0,(r2) bgt 3f dec r0 bge 2f 3: jsr r5,error; 19. / out of range clr r0 2: mov r5,-(sp) mpy r0,r5 add r5,r4 mov (sp)+,r5 mpy (r2)+,r5 jsr r5,getsym cmp r0,$36. / comma bne 1f dec (sp) bgt 1b jsr r5,error; 18. / wrong subscript count br 1b 1: cmp r0,$34. / ) beq 1f 9: jsr r5,error; 20. clr r0 1: cmp (sp)+,$1 beq 1f jsr r5,error; 18. / subscript count 1: mov (sp)+,r2 mov (sp)+,r3 movb symtab+1(r3),r5 mpy r4,r5 mov r5,r0 mov (sp)+/ / / quicker sort / mov $base,r1 / mov $base+[n*width],r2 / mov $width,r3 / jsr pc,qsort / r0,r1,r2,r3,r4 are used .globl qsort .globl compare qsort: mov r5,-(sp) mov r4,-(sp) bit $1,r3 bne 1f bit $1,r1 bne 1f cmp r3,$2 bne 2f mov $exch1,exchange br 3f 2: mov r3,r5 clc ror r5 mov r5,width mov $exchw,exchange br 3f 1: mov $exchb,exchange 3: jsr pc,qs1 mov (sp)+,r4 mov (sp)+,r5 rts pc qs1: mov r1,r5 neg r5 add r2,r5 bgt 1f rts pc 1: clr r4 dvd r3,r4 asr r4 mpy r3,r4 mov r5,r4 add r1,r4 mov r1,-(sp) mov r2,-(sp) loop: cmp r1,r4 bhis loop1 mov r1,r0 jsr pc,compare bgt loop1 add r3,r1 br loop loop1: cmp r2,r4 blos 1f sub r3,r2 mov r2,r0 jsr pc,compare bge loop1 jsr pc,*exchange cmp r1,r4 bne loop mov r2,r4 br loop 1: cmp r1,r4 beq 1f jsr pc,*exchange mov r1,r4 br loop1 1: mov (sp)+,r2 mov r4,-(sp) mov r4,r1 add r3,r1 mov r2,r0 sub r1,r0 sub 2(sp),r4 cmp r0,r4 blo 1f mov (sp)+,r0 mov (sp)+,r4 mov r1,-(sp) mov r2,-(sp) mov r0,r2 mov r4,r1 1: jsr pc,qs1 mov (sp)+,r2 mov (sp)+,r1 br qs1 exchb: mov r1,-(sp) mov r2,-(sp) mov r3,r5 1: movb (r1),r0 movb (r2),(r1)+ movb r0,(r2)+ sob r5,1b mov (sp)+,r2 mov (sp)+,r1 rts pc exchw: mov r1,-(sp) mov r2,-(sp) mov width,r5 1: mov (r1),r0 mov (r2),(r1)+ mov r0,(r2)+ sob r5,1b mov (sp)+,r2 mov (sp)+,r1 rts pc exch1: mov (r1),r0 mov (r2),(r1) mov r0,(r2) rts pc .bss exchange: .=.+2 width: .=.+2 o 1f mov (sp)+,r0 mov (sp)+,r4 mov r1,-(sp) mov r2,-(sp) mov r0,r2 mov/ / / fxx -- data segment definition .data .globl holround holround: 4 .bss / pass 1 .globl dimu dimu: .=.+2 / pass 2 .globl eqvtab / pass 3 stuff .globl conu .globl dou .globl blockp .globl dotabp .globl dotab .globl edotab .globl functn .globl blocks conu: .=.+2 dou: .=.+2 blockp: .=.+2 dotabp: .=.+2 dotab: .=.+60. edotab: functn: .=.+2 / pass 4 .globl negflg .globl repfact .globl contab .globl dattab negflg: .=.+2 repfact:.=.+2 / general buffer / 2200. for fc1, 15000. for fc2. xbufsiz = 2200. .globl xbuf xbuf: .=.+xbufsiz eqvtab = xbuf+518. / for pass 2 blocks = xbuf / for pass 3 dattab = xbuf+518. / for pass 4 contab = xbuf+xbufsiz / for all passes data: ibuf: .=.+518. obuf: .=.+518. tbuf: .=.+518. line: .=.+linsize eline: .=.+4 ifno: .=.+2 efno: .=.+2 errp: .=.+2 / init(errb) errb: .=.+12. eerrb: / size 0 mod 4 symtab: .=.+symsize esymtab: esymp: .=.+2 / init(esymtab) symtp: .=.+2 namebuf:.=.+namsize enamebuf: namep: .=.+2 / init(namebuf) .=.+40 /fake .=.+1 / make odd symbuf: .=.+smblsize / init(<_>) esymbuf: ch: .=.+1 ch1: .=.+1 progt: .=.+2 holquo: .=.+2 nxtaloc:.=.+2 imptab: .=.+[26.*2*2] / 26 letters, 2 alphabets, 2 bytes nerror: .=.+2 temp: .=.+2 functm: .=.+2 edata: dsize =.-data ize eline: .=.+4 ifno: .=.+2 efno: .=.+2 errp: .=.+2 / init(errb) errb: .=.+12. eerrb: / size 0 mod 4 symtab: .=.+symsize esymtab: esymp: .=.+2 / init(esymtab) symtp: .=.+2 namebuf:.=.+namsize enamebuf: namep: .=.+2 / init(namebuf) .=.+40 /fake .=.+1 / ma# include "../sccshead/sfile.h" # include "../sccshead/sint.h" # include "../sccshead/statbuf.h" char chghst_[] "~|^`chghist.c 3.3"; struct Packet gpkt; int hadr; int num_files; int release -1; int level -1; struct Statbuf sb; main(argc,argv) int argc; char *argv[]; { register int i; register char *p; char c; extern chghist(); for(i=1; iPupd = 1; dohead(pkt); dorelt(pkt); dodelt(pkt); dobody(pkt); wrtrec(pkt,0,-1); rename(auxf(&gpkt,'x'),gpkt.Pfile); xrm(pkt); } dorelt(pkt) struct Packet *pkt; { register struct Reltab *rt; while ((rt=getrec(pkt))->Rrel) { if (pkt->Prel == -1) pkt->Prel = rt->Rrel; if (pkt->Plev == -1 && pkt->Prel == rt->Rrel) pkt->Plev = rt->Rlevs; } } dodelt(pkt) register struct Packet *pkt; { register struct Deltab *dt; char type; register int didchg; struct Deltab ndt; didchg = 0; dohist(&ndt,0); while ((dt=getrec(pkt))->Drel) { if (!didchg && pkt->Prel == dt->Drel && pkt->Plev == dt->Dlev && ((type=dt->Dtype)=='D' || type=='P' || type=='U' || type=='I' || type=='E')) { chgpermiss(pkt,dt); didchg = 1; dt->Dtype = 'H'; ndt.Ddatetime = dt->Ddatetime; time(&dt->Ddatetime); copy(dt->Dpgmr,ndt.Dpgmr); copy(getlnam(),dt->Dpgmr); wrtrec(pkt,0,0); ndt.Dtype = type; ndt.Drel = pkt->Prel; ndt.Dlev = pkt->Plev; ndt.Dfill = ' '; wrtrec(pkt,&ndt,size(ndt.Dhist)+sizeof(ndt)- sizeof(ndt.Dhist)); } } if (!didchg) fatal("no delta (310)"); } chgpermiss(pkt,dt) register struct Packet *pkt; register struct Deltab *dt; { int fowner, downer, user; ckpfile(auxf(pkt,'p')); if (!equal(dt->Dpgmr,getlnam())) { fstat(pkt->Pibuf.Ifildes,&sb); fowner = sb.uid&0377; if (stat(dname(pkt->Pfile),&sb)) downer = -1; else downer = sb.uid&0377; user = getuid()&0377; if (user != fowner || user != downer) fatal("sorry (311)"); } } dobody(pkt) register struct Packet *pkt; { register struct Control *ctl; while (1) { ctl = getrec(pkt); if (ctlrec(ctl,pkt->Pibuf.Ilen) && ctl->Crel==0 && ctl->Clev==0) break; } } getrec(pkt) struct Packet *pkt; { if (rdrec(pkt)==1) fatal("premature eof (58)"); return(pkt->Pibuf.Irecptr); } fowner = sb.uid&0377; if (stat(dname(pkt->Pfile),&sb)) downer = -1; else downer = sb.uid&0377; user = getuid()&0377; if (user != fowner || user != downer) fatal("sorry (311)"); } } dobody(pkt) register struct Pa#include "../sccshead/sfile.h" #include "../sccshead/statbuf.h" #include "../sccshead/sint.h" # include "../sccshead/had.h" # define debug if(DEBUG) printf int DEBUG 0; char delta____[] "@(#)delta.c 3.13"; int num_files; char had[26]; long cutoff 0X7FFFFFFFL; /* max positive long */ int verbosity; int heur 3; int lookahd 50; char *why; struct Deltab ndt; main(argc,argv) int argc; char *argv[]; { register int i; register char *p; char c; int testmore; int needy; int intrp; extern delta(); extern char *acklist; needy = 0; for(i=1; i 3) fatal("bad heuristic level (7)"); break; case 'y': why = p; break; case 'l': if ((lookahd=patoi(p)) < 1) fatal("bad lookahead (8)"); break; case 'n': case 's': testmore++; break; default: fatal("unknown key letter (69)"); } if (testmore) { testmore = 0; if (*p) fatal(stringf( "value after %c arg (232)",c)); } if (had[c - 'a']++) fatal("key letter twice (464)"); argv[i] = 0; } else { if (argv[i][0] == '-') needy++; num_files++; } if(num_files == 0) fatal("missing file arg (49)"); if (needy && !HADY) fatal("missing history (326)"); if (!HADS) verbosity = WARNING; dohist(&ndt,why); if ((intrp=signal(2,1))==1) signal(1,1); else signal(2,intrp); setsig(); for (i=1; i 1 || had_dir || had_standinp)) printf("\n%s:\n",gpkt.Pfile); if (diff(gpkt.Pfile,gfile,lookahd)) { rename(auxf(&gpkt,'x'),gpkt.Pfile); xrm(&gpkt); remove(auxf(&gpkt,'p')); if (!HADN) { setuid(getuid()&0377); remove(gfile); } } if (!did_id && verbosity) msg2("No id keywords (305)\n"); xrm(&gpkt); freeall(); } /* Init sets up the `Info' structures for the two files, * calls opena() or openb(), and reads in the first window * for the given file. */ init(f,file,lookahead,which) struct Info **f; char file[], which; int lookahead; { register struct Info *p; register struct Ln *lp; register int i; i = (sizeof(*p)-sizeof(*lp)) + lookahead*sizeof(*lp); debug("(sizeof(*p)-sizeof(*lp))=%d sizeof(*lp)=%d\n", (sizeof(*p)-sizeof(*lp)),sizeof(*lp)); p = alloc(i,0); *f = p; p->Iwhich = which; p->Ilookahead = lookahead; p->Itop = 0; if (which == 'A') opena(p,file); else openb(p,file); for(i= -1; ++iIlines[i]; if(rdline(p,&lp->Ltext,&lp->Llen,&lp->Llnno) == -1) break; } p->Ilast = i; } /* Opena() does the initial SCCS file stuff. */ opena(p,mod) register struct Info *p; char mod[]; { register int f; char user[8]; p->Iinput = &gpkt; rdpfile(auxf(&gpkt,'p'),&gpkt.Prel,user); if (!equal(user,getlnam())) fatal("you are not `",user,"' (322)"); gpkt.Plev = -1; gpkt.Pcutoff = cutoff; doreltab(&gpkt); permiss(&gpkt); dodeltab(&gpkt); } /* Openb() does the initial text file stuff. */ openb(p,file) struct Info *p; char file[]; { p->Iinput = &bufb; opnl(p->Iinput,file); } /* Rdline() reads a line. * It determines if it should read the SCCS file or the text file. * It returns -1 on error or (equivalently) EOF, * and 0 on success. */ rdline(p,text,len,lnno) register struct Info *p; char **text; int *len, *lnno; { register struct Packet *pkt; register struct Ibufr *buf; if (p->Ieof) return(-1); if(p->Iwhich == 'A') { pkt = p->Iinput; if(readmod(pkt)) { p->Ieof = 1; close(pkt->Pibuf.Ifildes); return(-1); } *text = alloc((*len=pkt->Pibuf.Ilen)+1); move(pkt->Pibuf.Irecptr,*text,*len); (*text)[*len] = '\0'; *lnno = pkt->Precno; } else { buf = p->Iinput; if(getl(buf)==1) { p->Ieof = 1; close(buf->Ifildes); return(-1); } *text = alloc((*len=buf->Ilen-1)+1); move(buf->Irecptr,*text,*len); (*text)[*len] = '\0'; *lnno = ++curlnno; checkid(*text); } return(0); } /* * checkid() checks for "%.%" strings */ checkid(line) { extern did_id; register char *p; if (!did_id) for (p = line; *p; p++) if (p[0] == '%' && p[1] != 0 && p[2] == '%') { did_id = 1; break; } } /* Wrtctl() writes a control record. */ wrtctl(p,ctl) register struct Info *p; int ctl; { struct Control ctlrec; if (!wopen) wrtopn(p); ctlrec.Cctl = ctl; ctlrec.Crel = (p->Iinput)->Prel; ctlrec.Clev = (p->Iinput)->Plev + 1; wrtrec(&wpacket,&ctlrec,SIZEOFCONTROL); } /* Wrtopn() opens the SCCS file with the update (Pupd) * flag set. The x-file is generated by this instance * of the open SCCS file. */ wrtopn(p) struct Info *p; { register struct Packet *p1, *p2; extern int verbosity; p1 = &gpkt; p2 = wopen = &wpacket; zero(p2,sizeof(*p2)); copy(p1->Pfile,p2->Pfile); p2->Prel = p1->Prel; p2->Plev = p1->Plev; p2->Pupd = 1; p2->Pcutoff = cutoff; p2->Pwrttn = 1; p2->Pverbose = verbosity; opnr(&p2->Pibuf,p2->Pfile); dohead(p2); doreltab(p2); dodeltab(p2); } /* Wrtend() flushes the SCCS file (and the x-file). */ wrtend(p) struct Info *p; { if (!wopen) wrtopn(p); if (weof==0) while(readmod(&wpacket)==0); close(wpacket.Pibuf.Ifildes); wrtrec(&wpacket,0,-1); } /* Before() rolls the wpacket instance of the SCCS file to * the record before the record at the top of the window. */ before(p) register struct Info *p; { register int n; if(weof) return; if (!wopen) wrtopn(p); if (p->Ilast==0) n = 0; else n = (&p->Ilines[(p->Itop)%(p->Ilookahead)])->Llnno; if(wpacket.Precno == n) return; while(wpacket.Precno != n) if (weof=readmod(&wpacket)) break; } /* After() rolls the wpacket instance of the SCCS file to * the record after the record at the top of the window. */ after(p) struct Info *p; { before(p); wrtrec(&wpacket,0,0); } status() { printf("%d unchanged\n%d inserted\n%d deleted\n", unchanged,inserted,deleted); } /* Enter() is called by `dolist()' (which see), * and is used in processing the a_ argument. */ enter(fill1,fill2,r,l) { extern int ackrel, acklev, acknowl; if (ackrel==r && acklev==l) acknowl = 1; } /* Clean_up() is called by fatal(), which might be called * because of a signal being caught. */ clean_up() { xrm(&gpkt); } /* Mkdeltab() builds a new delta table entry. */ mkdeltab(pkt) struct Packet *pkt; { int level; extern long timenow; if (pkt->Pnoprop) { ndt.Dtype = 'U'; if (pkt->Pverbose&WARNING) msg2("Delta will not propagate (324)\n"); } else ndt.Dtype = 'D'; ndt.Drel = pkt->Prel; ndt.Dlev = level = (pkt->Plev+1); ndt.Dfill = ' '; ndt.Ddatetime = timenow; copy(getlnam(),ndt.Dpgmr); wrtrec(pkt,&ndt,size(ndt.Dhist)+sizeof(ndt)-sizeof(ndt.Dhist)); if (pkt->Pverbose&WARNING) printf("%d.%d\n",pkt->Prel,level); } /* Now comes the hard stuff! * Read this code very slowly and very carefully. */ diff(filea,fileb,lookahead) char filea[], fileb[]; int lookahead; { struct Info *ainfo, *binfo; int a[2], b[2], deg[2], len; register int pick; init(&ainfo,filea,lookahead,'A'); init(&binfo,fileb,lookahead,'B'); while(ainfo->Ilast && binfo->Ilast) { match(ainfo,binfo,ainfo->Ilast,1,a,b,deg,0); match(binfo,ainfo,b[0]-1,a[0]+1,b,a,deg,1); pick = choose(ainfo,binfo,a,b,deg); insert(ainfo,binfo,b[pick]-1); delete(ainfo,binfo,a[pick]-1); unchanged =+ deg[pick]; while(deg[pick]--) { take(ainfo,&len); take(binfo,&len); } while(ainfo->Ilast && binfo->Ilast) { if (equal( ainfo->Ilines[ainfo->Itop%ainfo->Ilookahead].Ltext, binfo->Ilines[binfo->Itop%binfo->Ilookahead].Ltext)) { take(ainfo,&len); take(binfo,&len); unchanged++; } else break; } }  while(binfo->Ilast) insert(ainfo,binfo,binfo->Ilast); while(ainfo->Ilast) delete(ainfo,binfo,ainfo->Ilast); wrtend(ainfo); if (!HADS) status(); if (!HADH) return(1); return(update()=='y'); } match(f1,f2,stop1,start2,mark1,mark2,deg,sub) register struct Info *f1, *f2; int stop1, start2, mark1[2], mark2[2], deg[2], sub; { register int i1; int i2, found; found = 0; for(i1=0; ++i1<=stop1;) { for(i2=start2-1; ++i2<=f2->Ilast;) if (equal( f1->Ilines[(f1->Itop+i1-1)%(f1->Ilookahead)].Ltext,  f2->Ilines[(f2->Itop+i2-1)%(f2->Ilookahead)].Ltext)){ found = 1; break; } if(found) break; } if(!found) { mark1[sub] = 0; mark2[sub] = f2->Ilast+1; deg[sub] = 0; return; } mark1[sub] = i1; mark2[sub] = i2; deg[sub] = 1; while(i1++ < f1->Ilast && i2++ < f2->Ilast && equal(f1->Ilines[(f1->Itop+i1-1)%(f1->Ilookahead)].Ltext, f2->Ilines[(f2->Itop+i2-1)%(f2->Ilookahead)].Ltext)) deg[sub]++; return; } insert(f1,f2,mark2) struct Info *f1, *f2; register int mark2; { register struct Control *rec; int len; if(mark2 < 1) return; inserted =+ mark2; before(f1); wrtctl(f1,INS); while(mark2--) { rec = take(f2,&len); if (ctlrec(rec,len)) fatal(stringf("illegal data on line %d (312)", oldlnno)); wrtrec(&wpacket,rec,len); } wrtctl(f1,END); } delete(f1,f2,mark1) struct Info *f1, *f2; register int mark1; { int len; if(mark1 < 1) return; deleted =+ mark1; before(f1); wrtctl(f1,DEL); while(--mark1) take(f1,&len); after(f1); take(f1,&len); wrtctl(f1,END); } take(p,len) register struct Info *p; int *len; { register struct Ln *lp; if(oldrec) free(oldrec); lp = &p->Ilines[p->Itop]; oldrec = lp->Ltext; oldlnno = lp->Llnno; *len = lp->Llen; if(rdline(p,&lp->Ltext,&lp->Llen,&lp->Llnno) == -1) p->Ilast--; if(++p->Itop == p->Ilookahead) p->Itop = 0; return(oldrec); } numsame(f1,f2,start1,start2) register struct Info *f1, *f2; int start1, start2; { register int i1; int i2, num; num = 0; for(i1=start1+1; i1<=f1->Ilast; i1++) for(i2=start2+1; i2<=f2->Ilast; i2++) if (equal( f1->Ilines[(f1->Itop+i1-1)%(f1->Ilookahead)].Ltext, f2->Ilines[(f2->Itop+i2-1)%(f2->Ilookahead)].Ltext)) { num =+ f1->Ilines[(f1->Itop+i1-1)% (f1->Ilookahead)].Llen; break; } return(num); } double reldiff(a,b) double a, b; { double x; if((1e-37 > -b) && (b < 1e-37)) return(1e37); x = (a - b)/b; if(x < 0) return(-x); return(x); } double W 1.; double X 2.; double Y 4.; double Z 8.; choose(ainfo,binfo,a,b,deg) register struct Info *ainfo, *binfo; int a[2], b[2], deg[2]; { register int i; int k, chars, avgline, nsame; double val[2]; if(heur == 0) return(ask(ainfo,binfo,a,b)); for(k=0; k<=1; k++) { chars = 0; for(i=a[k]; i>0 && iIlines[(ainfo->Itop+i-1)% (ainfo->Ilookahead)].Llen; avgline = (a[k]+b[k])/2; nsame=numsame(ainfo,binfo,a[k],b[k]); val[k] = -W*avgline + X*deg[k] + Y*chars + Z*nsame; } if(reldiff(val[0],val[1]) < .2) return(ask(ainfo,binfo,a,b)); if(heur==1 && b[0]!=1 && ((a[1]-a[0])>3 || (b[0]-b[1])>3)) return(ask(ainfo,binfo,a,b)); if(val[0] > val[1]) return(0); if(val[0] < val[1]) return(1); } /* If you've made it to here, congratulations! * The rest is easy. * * Ask() returns zero if lines were inserted, * non-zero if lines were deleted. */ ask(f1,f2,a,b) struct Info *f1, *f2; int a[2], b[2]; { if(heur == 3) return(0); while(1) { printf("%d inserted:\n",b[0]-(b[1]?b[1]:1)); if(answer(f2,b[1]) == 'y') return(0); printf("%d deleted:\n",a[1]-(a[0]?a[0]:1));  if(answer(f1,a[0]) == 'y') return(1); printf("try again...\n"); } } /* Answer() solicits a response from the user * and prints the next line in the buffer if the response * was only a new-line. * It returns the response (which must be either `y' or `n'). */ answer(p,ln) struct Info *p; int ln; { char resp; if(!ln) ln++; printf(" %s\n", p->Ilines[(p->Itop+(ln++)-1)%(p->Ilookahead)].Ltext); if(!(noteach++)) printf("(y,n,s,CR)"); printf("? "); while((resp=getresp("(y,n,s,CR)?")) == '\n') { if(ln > p->Ilast) printf("end of buffer\n?"); else printf(" %s\n?", p->Ilines[(p->Itop+(ln++)-1)%(p->Ilookahead)].Ltext); } return(resp); } /* Getresp() gets a response from the user about `lesson'. * It processes all responses other than `y', `n', and * new-line. */ getresp(lesson) char lesson[]; { char resp, nextc; while(1) { resp = getchr(); if(resp == '\n') return('\n'); if((nextc=getchr()) != '\n') while(getchr() != '\n'); if(resp == 's' && nextc == '\n') { status(); printf("? "); continue; } if((resp != 'y' && resp != 'n') || nextc != '\n') { printf(lesson); continue; } return(resp); } } /* Update() solicits a `y'/`n' response from the user. */ update() { char resp; printf("update"); if(!(noteach++)) printf("(y,n)"); do { printf("? "); resp=getresp("(y,n)?"); } while(resp == '\n'); return(resp); } if(resp == '\n') return('\n'); if((nextc=getchr()) != '\n') while(getchr() != '\n'); if(resp == 's' && nextc == '\n') { status(); printf#include "../sccshead/sfile.h" #include "../sccshead/statbuf.h" #include "../sccshead/sint.h" # include "../sccshead/had.h" char get____[] "~|^`get.c 3.17"; int num_files; char had[26]; char *ilist, *elist, *lfile; int release -1; int level -1; long cutoff 0X7FFFFFFFL; /* max positive long */ int verbosity; main(argc,argv) int argc; register char *argv[]; { register int i; register char *p; char c; int testmore; extern get(), fout; for(i=1; i 1 || had_dir || had_standinp)) printf("\n%s:\n",gpkt.Pfile); if (!HADE && gpkt.Plev == 0) fatal("level zero not allowed (304)"); if(HADE && gpkt.Plev != -1) fatal("level not allowed with e (46)"); if(HADE && HADM) fatal("e not allowed with m (227)"); if(HADE || HADI || HADX) HADK = 1; did_id = 0; dohead(&gpkt); doreltab(&gpkt); if (!HADP) { file = auxf(&gpkt,'g'); if (access(file,2)==0) fatal("writable `",file,"' exists (215)"); } if(HADE) { permiss(&gpkt); file = auxf(&gpkt,'p'); ckpfile(file); wrtpfile(file,gpkt.Prel); } setuid(getuid()&0377); doie(); dodeltab(&gpkt); datetime(&gpkt); gopen = 0; copy(auxf(&gpkt,'g'),gfile); while(!readmod(&gpkt)) { if(!gopen) { gopen = 1; if(!HADP) { crtl(&obuf,gfile,HADK?0644:0444); } else crtl(&obuf,0,0,1); } p = &gpkt.Pibuf.Irecptr[gpkt.Pibuf.Ilen]; c = *p; *p = 0; if ((l=idsubst(&gpkt,gpkt.Pibuf.Irecptr))==gpkt.Pibuf.Irecptr) { if ((l=prfx(&gpkt,l,0)) == gpkt.Pibuf.Irecptr) *p = '\n'; } else l = prfx(&gpkt,l,1); putl(&obuf,l); *p = c; } if(gopen) { flshl(&obuf); if(!HADP) close(obuf.Ofildes); } if (gpkt.Pverbose&NLINES) printf("%d lines\n",gpkt.Plnno); if (!did_id && !HADK && gpkt.Pverbose&WARNING) msg2("No id keywords (305)\n"); close(gpkt.Pibuf.Ifildes); freeall(); } doie() /* process included and excluded deltas */ { if(HADI) { if (gpkt.Pverbose&DOLIST) printf("Included:\n"); dolist(&gpkt,ilist,'i'); } if(HADX) { if (gpkt.Pverbose&DOLIST) printf("Excluded:\n"); dolist(&gpkt,elist,'e'); } } enter(pkt,ch,r,l) /* called by dolist() */ register struct Packet *pkt; char ch; register int r, l; { switch(pkt->Papply[r][l].Acode) { case EMPTY: pkt->Papply[r][l].Acode = (ch=='I'?APPLY:NOAPPLY); return; case APPLY: fatal(stringf("%d.%d already included (229)",r,l)); case NOAPPLY: fatal(stringf("%d.%d already excluded (230)",r,l)); default: fatal("internal error in get/enter() (231)"); } } char curdate[9]; /* current date (YY/MM/DD) */ char gdate[9]; /* current date (MM/DD/YY) */ char curtime[9]; /* current time (HH:MM:SS) */ char chgdate[9]; /* newest-applied-delta date (YY/MM/DD) */ char gchgdate[9]; /* newest-applied-delta date (MM/DD/YY) */ char chgtime[9]; /* newest-applied-delta time (HH:MM:SS) */ datetime(pkt) /* initialize date & time keywords */ struct Packet *pkt; { struct Time *lcltm; extern long timenow; lcltm = localtime(&timenow); copy(stringf("%d/%s/%s",lcltm->Tyear,zp(lcltm->Tmonth+1), zp(lcltm->Tday_month)),curdate); copy(stringf("%d/%d/%d",lcltm->Tmonth+1,lcltm->Tday_month, lcltm->Tyear),gdate); copy(stringf("%s:%s:%s",zp(lcltm->Thours),zp(lcltm->Tminutes), zp(lcltm->Tseconds)),curtime); lcltm = localtime(&pkt->Pcdt); copy(stringf("%d/%s/%s",lcltm->Tyear,zp(lcltm->Tmonth+1), zp(lcltm->Tday_month)),chgdate); copy(stringf("%d/%d/%d",lcltm->Tmonth+1,lcltm->Tday_month, lcltm->Tyear),gchgdate); copy(stringf("%s:%s:%s",zp(lcltm->Thours),zp(lcltm->Tminutes), zp(lcltm->Tseconds)),chgtime); } static char zkeywd[5] "@(#)"; idsubst(pkt,line) /* substitute for identification keywords */ register struct Packet *pkt; char line[]; { static char tline[256]; register char *lp, *tp; if(HADK) return(line); for(lp=line; *lp != '%'; lp++) if(*lp == 0) return(line); tp = tline; for(lp=line; *lp != 0; lp++) { if(*lp == '%' && *(lp+1) != 0 && *(lp+2) == '%') switch(*++lp) { case 'M': tp = trans(tp,gfile); lp++; continue; case 'R': tp = trans(tp, stringf("%d",pkt->Prel)); lp++; continue; case 'L': tp = trans(tp, stringf("%d",pkt->Plev)); lp++; continue; case 'D': tp = trans(tp,curdate); lp++;  continue; case 'H': tp = trans(tp,gdate); lp++; continue; case 'T': tp = trans(tp,curtime); lp++; continue; case 'E': tp = trans(tp,chgdate); lp++; continue; case 'G': tp = trans(tp,gchgdate); lp++; continue; case 'U': tp = trans(tp,chgtime); lp++; continue; case 'X': tp = trans(tp, stringf("%c",pkt->Punack?'P':' ')); lp++; continue; /* Use stringf so that what won't  recognize this instance of the what string. */ case 'Z': tp = trans(tp,zkeywd); lp++; continue; case 'P': tp = trans(tp,pkt->Phdr.Hpers); lp++; continue; case 'S': tp = trans(tp,pkt->Phdr.Hdesc); lp++; continue; case 'Y': tp = trans(tp,pkt->Phdr.Htype); lp++; continue; case 'I': tp = trans(tp, stringf("%d.%d",pkt->Prel,pkt->Plev)); lp++; continue; case 'F': tp = trans(tp,pkt->Pfile); lp++; continue; case 'W': tp = trans(tp, stringf("%s%s\t%d.%d",zkeywd,gfile, pkt->Prel,pkt->Plev)); lp++; continue; case 'C': tp = trans(tp,stringf("%u",pkt->Plnno)); lp++; continue; default: *tp++ = '%'; break; } *tp++ = *lp; } *tp = 0; return(tline); } trans(tp,str) register char *tp, *str; { did_id = 1; while(*tp++ = *str++); return(tp-1); } prfx(pkt,line,copyflag) /* processing for -m and -n args */ register struct Packet *pkt; char line[]; { static char pline[290]; register char *p; if (HADM && HADN) p = copy(stringf("%s\t%4d.%-4d\t",gfile,pkt->Pirel,pkt->Pilev), pline); else if (HADM) p = copy(stringf("%4d.%-4d\t",pkt->Pirel,pkt->Pilev),pline); else if (HADN) p = copy(stringf("%s\t",gfile),pline); else { if (!copyflag) return(line); p = pline; } p = copy(line,p); *p = '\n'; return(pline); } zp(n) /* date & time zero padding */ register int n; { register char *r, *s; r = alloc(4,1); s = stringf("%d",n);  if(s[1] == '\0') { r[0] = '0'; r[1] = s[0]; } else copy(s,r); return(r); } wrtrec(){} /* prevent loading of real wrtrec() */ mkdeltab(){} /* prevent loading of real mkdeltab() */ kt->Pirel,pkt->Pilev),pline); else if (HADN) p = copy(stringf("%s\t",gfile),pline); else { if (!copyflag) return(line); p = pline; } p = copy(line,p); *p = '\n'; return(pline); } zp(n) /* date & time zero padding */ register int n; { register char *r, *s; r = alloc(4,1); s = stringf("%d",n); #include "../sccshead/sfile.h" #include "../sccshead/statbuf.h" #include "../sccshead/sint.h" # include "../sccshead/had.h" int num_files; char had[26]; # define MINR 1 # define MAXR 9999 # define DESCSIZE 100 # define PERSONSIZE 14 # define TYPESIZE 10 char admin_____[] "~|^`admin.c: 3.6"; int irel, ceil, floor, numlocks, numulocks, rdef, fexists, didargs; int lock[5], unlock[5]; char *desc, *person, *type, *ifile; /* aulist is the list of users to be added to Hulist, * eulist is the list of users to be erased from Hulist. */ char aulist[32]; /* initialized to zero */ char eulist[32] { 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, 0377, }; struct Ibufr pbuf; main(argc,argv) int argc; char *argv[]; { register int j; register char *p; char c; int testmore, testklt; int i; int uid, mask, k; extern admin(); opnl(&pbuf,"/etc/passwd"); testklt = 1;  for(j=1; j DESCSIZE) fatal("description too large (471)"); break; case 'p': person = p; if (size(person) > PERSONSIZE) fatal("person too large (472)"); break; case 't': type = p; if (size(type) > TYPESIZE) fatal("type too large (473)"); break; case 'i': ifile = p; break; case 'r': if ((irel = patoi(p)) == -1) fatal("bad r argument (454)"); if ((irel < MINR) || (irel > MAXR)) fatal("bad r argument (455)"); break; case 'c': if ((ceil = patoi(p)) == -1) fatal("bad ceiling (450)"); if ((ceil < MINR) || (ceil > MAXR)) fatal("bad ceiling (451)"); break; case 'f': if ((floor = patoi(p)) == -1) fatal("bad floor (452)"); if ((floor < MINR) || (floor > MAXR)) fatal("bad floor (453)"); break; case 'l': testklt = 0;  if (numlocks >= 5) fatal("too many locks (456)"); if ((i = patoi(p)) == -1) fatal("bad lock (457)"); if ((i < MINR) || (i > MAXR)) fatal ("bad lock (458)"); chkr(i); lock[numlocks++] = i; break; case 'u': testklt = 0; if (numulocks >= 5) fatal("too many unlocks (459)"); if ((i = patoi(p)) == -1) fatal("bad unlock (460)"); if ((i < MINR) || (i > MAXR)) fatal("bad unlock (461)"); chkr(i); unlock[numulocks++] = i; break; case 'a': testklt = 0; uid = getluid(p); mask = 1; for (k=uid&7; k; k--) mask =<< 1; aulist[uid>>3] =| mask; break; case 'e': testklt = 0; if ((uid = patoi(p))== -1) uid = getluid(p); mask = 1; for (k=uid&7; k; k--) mask =<< 1; eulist[uid>>3] =& ~mask; break; case 'y': if ((rdef = patoi(p)) == -1) fatal("bad y argument (462)"); if ((rdefMAXR) && rdef!=0) fatal("bad y argument (463)"); break; case 'z': case 'n':  testmore++; break; default: fatal("unknown key letter (69)"); } if (testmore) { testmore = 0; if (*p) fatal(stringf( "value after %c arg (232)",c)); } if (had[c - 'a']++ && testklt++) fatal("key letter twice (464)"); argv[j] = 0; } else num_files++; if(num_files == 0) fatal("missing file arg (49)"); setsig(fatal,fatal,fatal); for (j=1; j 0) fatal("more than one file (465)"); if (HADI) HADN = 1; if (HADN && fexists) fatal("file exists (466)"); if (!HADN && !fexists) fatal("file does not exist (467)"); if (fexists) { chmod(afile,fexists|(IREAD|IWRITE)); fd = xopen(afile,2); chmod(afile,fexists); seek(fd,2,0); if (read(fd,hdr,sizeof(*hdr))!=sizeof(*hdr)) fatal("read error (468)"); ohash = hash(hdr,&hdr->Hash); if (hdr->Hash==0) HADZ = 1; } else { crtr(&obuf,afile,0444); hdr->Hmagicno = MAGICNO; } if (HADD) copy(desc,hdr->Hdesc); if (HADP) copy(person,hdr->Hpers); if (HADT) copy(type,hdr->Htype); if (HADC) hdr->Hceil = ceil; if (HADF) hdr->Hfloor = floor; if (HADU) { for (k=0; kHsw[i]==unlock[k]) hdr->Hsw[i] = chkunlk[k] = 0; } for (k=0; kHsw[k]==0) for (i=k+1; i<5; i++) if (hdr->Hsw[k] = hdr->Hsw[i]) {  hdr->Hsw[i] = 0; break; } } if (HADL) { for (k=0; k<5; k++) if (hdr->Hsw[k]==0) break; for (i=0; iHsw[k++] = lock[i]; } } if (HADA) for (i=0; i<32; i++) hdr->Hulist[i] =| aulist[i]; if (HADE) for (i=0; i<32; i++) hdr->Hulist[i] =& eulist[i]; if (HADY) hdr->Hrdef = rdef; if (fexists) { nhash = hash(hdr,&hdr->Hash); hdr->Hash =+ nhash-ohash; if (HADZ) hdr->Hash = 0; seek(fd,2,0); if (write(fd,hdr,sizeof(*hdr))!=sizeof(*hdr)) fatal("write error (474)"); close(fd); return; } /* Thie following is really a large else clause * to complement the `if (fexists)' above. * I.e., we get here if the file did not exist. */ putr(&obuf,hdr,sizeof(*hdr)); if (HADI) { if (HADR) rel = rt.Rrel = irel; else rel = rt.Rrel = 1; rt.Rlevs = 1; putr(&obuf,&rt,sizeof(rt)); } rt.Rrel = rt.Rlevs = 0; putr(&obuf,&rt,sizeof(rt)); dt.Dtype = 'D'; dt.Dfill = ' '; time(&dt.Ddatetime); if ((cp=getlnam())==0) fatal("Who are you? (75)"); copy(cp,dt.Dpgmr); dt.Dhist[0] = '\0'; if (HADI) { dt.Drel = rel; dt.Dlev = 1; putr(&obuf,&dt,sizeof(dt)-(sizeof(dt.Dhist)-1)); } dt.Drel = dt.Dlev = 0; putr(&obuf,&dt,sizeof(dt)-(sizeof(dt.Dhist)-1)); if (HADI) { ctl.Crel = rel; ctl.Clev = 1; ctl.Cctl = INS; putr(&obuf,&ctl,SIZEOFCONTROL); if (*ifile) opnl(&ibuf,ifile); else opnl(&ibuf,0,0); for (k = 1; getl(&ibuf) != 1; k++) { cp = ibuf.Irecptr; i = ibuf.Ilen - 1; cp[i] = 0; if (ctlrec(cp,i)) fatal(stringf("illegal data on line %d (312)", k)); putr(&obuf,cp,i); } close(ibuf.Ifildes); ctl.Cctl = END; putr(&obuf,&ctl,SIZEOFCONTROL); } ctl.Crel = ctl.Clev = 0; ctl.Cctl = END; putr(&obuf,&ctl,SIZEOFCONTROL); flshr(&obuf,HADZ); close(obuf.Ofildes); } /* This is really a typo check (if you type the same release * number twice this routine catches it). */ chkr(r) { register int i; for (i=0; iIrecptr)=='*') continue; if (*p=='-') { p[buf->Ilen-1] = 0; if (equal(++p,key)) return; } } fatal("not found (83)"); } } while ((line=getl(&buf))!=1 && line[0] != '-'); exit(0); } ask() { static char resp[50]; register char *r; printf("msg number or comd name? "); r = resp; # /* PURPOSE - what -- find and print sccs id information */ /* RESPONSIBLE PROGRAMMER D.B.Knudsen 4/9/75 M.J.Rochkind 1/18/74 */ /* PROPRIETARY NOTICE This information is proprietary and is the property of Bell Telephone Laboratories, Incorporated. Its reproduction or disclosure to others, either orally or in writing, is prohibited without written permission of Bell Laboratories. PROPRIETARY NOTICE */ /* SCCS ID INFO */ char what__[] "@(#)what.c 3.1 12/29/76 11:56:59 %O%"; /* SCCS ID INFO */ #define NEXTCHAR (CHAR=getc(&buf)) #define EOF -1 char pattern[] "@(#)"; char opattern[] "~|^`"; char noopen[] "can't open "; struct {int fildes; int nleft; char *nextp; char buffer[512]; } buf; main(argc,argv) int argc; char *argv[]; { register int CHAR,i; register char c; while (--argc) { if (fopen(argv++[1],&buf)<0) { write(2,noopen,length(noopen)); write(2,argv[0],length(argv[0])); write(2," (26)\n",6); continue; } write(1,argv[0],length(argv[0])); write(1,":\n",2); while (NEXTCHAR!= EOF) findpat: if (CHAR==pattern[0]) { for (i=1;c=pattern[i++];) if (NEXTCHAR!=c) goto findpat; putchar('\t'); while (NEXTCHAR && CHAR!='"' && CHAR!= -1 && CHAR!='>' && CHAR!='\n')putchar(CHAR); putchar('\n'); } else if (CHAR==opattern[0]) { for (i=1;c=opattern[i++];) if (NEXTCHAR!=c) goto findpat; putchar('\t'); while (NEXTCHAR && CHAR!='"' && CHAR!= -1 && CHAR!='>' && CHAR!='\n')putchar(CHAR); putchar('\n'); } close(buf.fildes); } } length(st) char *st; {register int i; for (i=0;st[i];i++); return i; } ];) if (NEXTCHAR!=c) goto findpat; putchar('\t'); while (NEXTCHAR && CHAR!='"' && CHAR!= -1 && CHAR!='>' && CHAR!='\n')putchar(CHAR); putchar('\n'); } else if (CHAR==opattern[0]) { for (i=1;c=opattern[i++];) if (NEXTCHAR!=c) goto findpat; putchar('\t'); while (NEXTCHAR && CHAR!='"' && CHAR!= -1 && CHAR!='>' && CHAR!='\n')putchar(CHAR); putchar('\n'); } close(buf.fildes); } }#include "../sccshead/sfile.h" #include "../sccshead/statbuf.h" #include "../sccshead/sint.h" # include "../sccshead/had.h" char prt____[] "~|^`prt.c 3.11"; int num_files; char had[26]; int release; int level; int grelease -1; int glevel -1; long cutoff; int start, prefix; int rofflen 0; char newline[] "\n"; main(argc,argv) int argc; char *argv[]; { register int i; register char *p; char c; extern prt(), fout; for(i=1; i0) printf(".ti 0\n"); } recnum = block = offset = 0; release = grelease; level = glevel; if ((HADP|(i=HADS|HADH|HADR|HADD|HADB))==0) HADD = 1; else if (i==0) HADS = start = 1; if (HADP) doactual(); else dointerp(); flush(); close(ibuf.Ifildes); } /* Routine to read the next record. * Computes block, offset, and record number. * Handles EOF. * Prints block, offset, and record number if required. */ nextrec(outyes) int outyes; { register char *p; if ((block+offset)==0) offset = 1; else { offset =+ ibuf.Ilen + !(ibuf.Ilen&1) + 1; block =+ offset>>9; offset =& 0777; } if ((p=getr(&ibuf))==1) fatal("premature eof (58)"); recnum++; if (HADP && outyes) out(stringf("RECORD #: %-6d BLOCK: %-6d OFFSET: %d\n", recnum,block,offset)); return(p); } /* Prints uninterpreted file. * Processes header and release table. */ doactual() { register struct Header *hdr; register struct Reltab *rt; if (HADS) HADH = HADR = HADD = HADB = 1; else start = 1; hdr = nextrec(HADH); if (HADH) { out(stringf("Magic number: %d ",hdr->Hmagicno)); out(stringf("Default release: %d ",hdr->Hrdef)); if (!HADX) out(stringf("Hash: %d (0%o)\n",ibuf.Ihtot,ibuf.Ihtot)); else out(newline); dobeg(hdr); out(stringf("Floor: %d Ceiling: %d Locks: ", hdr->Hfloor,hdr->Hceil)); out(stringf("%5d%5d%5d%5d%5d\n",hdr->Hsw[0], hdr->Hsw[1],hdr->Hsw[2],hdr->Hsw[3],hdr->Hsw[4])); dowho(hdr); } if ((HADR|HADD|HADB)==0) return; for (rt=nextrec(HADR); rt->Rrel; rt=nextrec(HADR)) if (HADR) out(stringf("Release %d: %d levels\n", rt->Rrel,rt->Rlevs)); if (HADR) out(stringf("Release 0: %d levels\n",rt->Rlevs)); if ((HADD|HADB)==0) return; dodel(); if (HADB==0) return; dobod(); } /* Prints interpreted file. * Processes header and release table. */ dointerp() { register struct Header *hdr; int i, rdef, found; register struct Reltab *rt; start = 1; hdr = nextrec(HADH); if (hdr->Hmagicno!=MAGICNO) fatal("not an SCCS file (421)"); if (HADH) { dobeg(hdr); if ((i=hdr->Hfloor)==0) i = 1; out(stringf("Floor: %d ",i)); if ((i=hdr->Hceil)==0) i = 9999; out(stringf("Ceiling: %d ",i)); found = 0; out("Locked releases:"); for (i=0; i<5; i++) if (hdr->Hsw[i]) { out(stringf("%5d",hdr->Hsw[i])); found++; } if (found) out(newline); else out(" none\n"); dowho(hdr); } rdef = hdr->Hrdef; rt = nextrec(HADR); if (rdef==0 && (rdef=rt->Rrel)==0) rdef = 1; if (HADH) out(stringf("Default release: %d\n",rdef)); if ((HADR|HADD|HADB)==0) return; if (HADY && release == -1) release = rdef; for (; rt->Rrel; rt = nextrec(HADR)) { if (HADR) { out(stringf("Release %d: %d levels\n", rt->Rrel,rt->Rlevs)); } if (level == -1 && rt->Rrel == release) level = rt->Rlevs; } if ((HADD|HADB)==0) return; dodel(); if (HADB==0) return; dobod(); } /* Print header data. * Common to both doactual and dointerp. */ dobeg(ahdr) struct Header *ahdr; { register struct Header *hdr; register int found; found = 0; if (hdr->Htype[0]) { found++; out(stringf("Type: %-9s ",hdr->Htype)); } if (hdr->Hpers[0]) { found++; out(stringf("Person: %-6s ",hdr->Hpers)); } if (hdr->Hdesc[0]) { found++; out(stringf("Description: %s",hdr->Hdesc)); } if (found) out(newline); } /* Prints user list (Hulist). * Common to both doactual and dointerp. */ dowho(ahdr) struct Header *ahdr; { register struct Header *hdr; register int mask, j; int i, found, cnt; char *p; hdr = ahdr; found = 0; out("Who may add deltas: "); cnt = 3; for (i=0; i<32; i++) { mask = 1; for (j=0; j<8; j++) { if (hdr->Hulist[i]&mask) { found++; if (p=getlnam((i<<3)+j)) out(stringf("%7s",p)); else out(stringf("%7d",(i<<3)+j)); if (++cnt==10) { cnt = 0; out(newline); } } mask =<< 1; } } if (found==0) out("everyone\n"); else if (cnt) out(newline); } /* Prints delta table. * Processes both actual and interpreted and x arg. */ dodel() { register struct Deltab *dt; register char c; for (dt=nextrec(HADD); dt->Drel; dt=nextrec(HADD)) { if (dt->Ddatetime < cutoff) HADD = 0; if (HADD) if (!doadel(dt)) continue; if (dt->Drel == release && dt->Dlev == level) HADD = 0; } if (HADD) { if (HADP) { out(deltastr(0,0,dt->Dtype,dt->Drel,dt->Dlev, HADX?(&xtime):(&dt->Ddatetime), dt->Dpgmr,dt->Dhist)); out(newline); }  else { if (prefix) out(stringf("%s:\t",pfile)); if (HADC) { out(datetime(&dt->Ddatetime)); out("created by "); out(dt->Dpgmr); out(newline); } else out(stringf("File created by %s on %s", dt->Dpgmr,ctime(HADX?&xtime:&dt->Ddatetime))); } } } doadel(dt) register struct Deltab *dt; { register char c; register int rc; rc = (c=dt->Dtype) != 'R' && c != 'H' && c != 'C'; if (HADA || rc) { if (prefix) out(stringf("%s:\t",pfile)); if (HADC) { out(datetime(&dt->Ddatetime)); out(stringf("%c%4d.%-4d%-6s ",dt->Dtype, dt->Drel,dt->Dlev,dt->Dpgmr)); out(dt->Dhist); } else { out(deltastr(0,0,dt->Dtype,dt->Drel,dt->Dlev, HADX?&xtime:&dt->Ddatetime, dt->Dpgmr,dt->Dhist)); } out(newline); } return(rc); } /* Prints body. * Processes both actual and interpreted. */ dobod() { register struct Control *ctl; register struct Line *lp; char c; for (ctl=nextrec(HADB); !(ctlrec(ctl,ibuf.Ilen) && ctl->Crel==0); ctl=nextrec(HADB)) { if (ctlrec(ctl,ibuf.Ilen)) out(stringf("*** %c %d.%d\n", "EDI"[ctl->Cctl-END],ctl->Crel,ctl->Clev)); else if (ibuf.Ilen) { c = (lp=ctl)->Lline[ibuf.Ilen]; lp->Lline[ibuf.Ilen] = '\0'; out(stringf("\t%s\n",lp->Lline)); lp->Lline[ibuf.Ilen] = c; } else out(newline); } if (HADP) out(stringf("*** %c %d.%d\n","EDI"[ctl->Cctl+13], ctl->Crel,ctl->Clev)); } /* Print string (via putchar). * Handles starting record number. */ out(s) char *s; { register char *p; if (start>recnum) return; for (p=s; *p; p++) { putchar(*p); if (*p== '\n' && rofflen>0) { out(".ti 0"); putchar('\n'); } } } datetime(tvec) long *tvec; { register struct Time *lcltm; lcltm = localtime(tvec); prtime(lcltm->Tyear,'/'); prtime(lcltm->Tmonth+1,'/'); prtime(lcltm->Tday_month,' '); prtime(lcltm->Thours,':'); prtime(lcltm->Tminutes,':'); prtime(lcltm->Tseconds,'\t'); } prtime(n,c) register int n,c; { char s[4]; s[0] = n/10 + '0'; s[1] = n%10 + '0'; s[2] = c; s[3] = 0; out(s); } rn; for (p=s; *p; p++) { putchar(*p); if (*p== '\n' && rofflen>0) { out(".ti 0"); putchar('\n'); } } } datetime(tvec) long *tvec; { register struct Time *lcltm; lcltm = localtime(tvec); prtime(lcltm->Tyear,'/'); prtime(lcltm->Tmonth+1,'/'); prtime(lcltm->Tday_month,' '); prtime(lcltm->Thours,':'); prtime(lcltm->Tminutes,':'); prtime(lcltm->Tseconds,'\t'); } prtime(n,c) register int n,c; { char s[4]; s[0] = n/10 + '0'; s[1] = n%10 + '0'; s[2] = c; s[3] = 0; out(s);# include "../sccshead/sfile.h" # include "../sccshead/sint.h" # include "../sccshead/statbuf.h" char rmdel_[] "~|^`rmdel.c 3.5"; struct Packet gpkt; int hadr; int num_files; int release; int level; struct Statbuf sb; main(argc,argv) int argc; char *argv[]; { register int i; register char *p; char c; extern rmdel(); for(i=1; iPlev== -1) fatal("no level specified (411)"); pkt->Pupd = 1; dohead(pkt); dorelt(pkt); dodelt(pkt); dobody(pkt); wrtrec(pkt,0,-1); rename(auxf(&gpkt,'x'),gpkt.Pfile); xrm(pkt); } dorelt(pkt) struct Packet *pkt; { register struct Reltab *rt; while ((rt=getrec(pkt))->Rrel) if (rt->Rrel==pkt->Prel && --(rt->Rlevs)==0) pkt->Pwrttn = 1; } dodelt(pkt) struct Packet *pkt; { register struct Deltab *dt; register int didrm; register char type; didrm = 0; while ((dt=getrec(pkt))->Drel) { if (!didrm && ((type=dt->Dtype)=='D' || type=='P' || type=='U' || type=='I' || type=='E')) { didrm = 1; dt->Dtype = 'R'; rmpermiss(pkt,dt); } } if (!didrm) fatal("no delta (310)"); } rmpermiss(pkt,dt) register struct Packet *pkt; register struct Deltab *dt; { char lname[SZLNAM], *username, *pfile; int r, fowner, downer, user; if (exists(pfile = auxf(pkt,'p'))) { rdpfile(pfile,&r,lname); if (!equal(lname,username = getlnam())) fatal("you are not `",lname,"' (307)"); if (!equal(dt->Dpgmr,username)) fatal("you are not `",dt->Dpgmr,"' (308)"); } else { fstat(pkt->Pibuf.Ifildes,&sb); fowner = sb.uid&0377; if (stat(dname(pkt->Pfile),&sb)) downer = -1; else downer = sb.uid&0377; user = getuid()&0377; if (user != fowner || user != downer) fatal("sorry (309)"); } if (dt->Drel!=pkt->Prel || dt->Dlev!=pkt->Plev) fatal("not the most recent delta (416)"); } dobody(pkt) register struct Packet *pkt; { register struct Control *ctl; register int keep; int rel, lev; rel = pkt->Prel; lev = pkt->Plev; keep = YES; while (1) { ctl = getrec(pkt); if (ctlrec(ctl,pkt->Pibuf.Ilen)) { if (ctl->Crel==rel && ctl->Clev==lev) { pkt->Pwrttn = 1; if (ctl->Cctl==INS) keep=NO; else keep=YES; } else if (ctl->Crel==0 && ctl->Clev==0) return; } else if (keep==NO) pkt->Pwrttn = 1; } } getrec(pkt) struct Packet *pkt; { if (rdrec(pkt)==1) fatal("premature eof (58)"); return(pkt->Pibuf.Irecptr); } struct Control *ctl; register int keep; int rel, lev; r# /* reform: 2.5 of 2/13/76: reformat file (esp non-UNIX source code)*/ /* NTABS = max # tab settings + 1 */ /* NCOLS = max size of untabbed line */ #define NTABS 21 #define NCOLS 512 #define ESC 033 int tabin[NTABS],tabout[NTABS]; char *tspec[2]; /* ptrs to tabspec1 & 2 */ /* following used to agree with manual page description */ #define TSPEC1 tspec[0] #define TSPEC2 tspec[1] int ntspec; /* number of tabspecs found so far */ int maxtab NCOLS; /* option flags */ int optb, /* >0 ==> blank out 1st optb chars if blank/digits */ opte, /* >0 ==> extend length of each line to opte */ optf, /* >0 ==> write format line in front of file */ opti 1, /* # of interior blanks required to make tab */ optm, /* >0 ==> move left optm characters */ optp, /* >0 ==> prepend optp characters */ opts, /* >0 ==> SCCS R.L moved to end of line */ optt; /* >0 ==> truncate lines to optt chars */ char line[2*NCOLS+1]; /* line working buffer */ char *pfirst, *plast; /* ptr to 1st, last (nl) chars of line */ char *liner, *linel; /* rightmost legal position */ /* leftmost legal position */ char srelev[10]; /* if +s, save SCCS R.L: RRRR.LLLLtab */ #define CARDSIZ 132 char card[CARDSIZ]; /* buffer area for 1st card in file */ char found; /* flag to note existence of format spec */ struct buf { int fildes; /* file descriptor */ int nleft; /* bytes left */ char *nextp; /* ptr to next char */ char buffer[512]; /* i/o area */ } fin, fout; char reform__[] "~|^`s.reform.c 2.5"; main(argc,argv) int argc; char **argv; { liner = line + 2*NCOLS; linel = line; /* init of linel and liner */ get1line(); /* initialize input buffer with 1 line (at least) */ options(argc,argv); fout.fildes = 1; if (optf) fwrite(); /* format spec into new file */ while (getline(tabin) >= 0) { if (optp) prepend(optp); if (optt) truncate(optt); remtrail(); if (opte) extend(opte); if (opts) sccsadd(); if (optb) blankout(optb); if (optm) movleft(optm); contract(tabout,opti); } fflush(&fout); exit(0); } /* get1line: prime fin buffer with 1st line (for use with -- tabspecs) */ get1line() /* leaves fin so that line is effectively reread by getchal */ { register int i; register char *p; fin.nextp = p = &fin.buffer[0]; for (i = 0; i <= 511;) { if (read(0, p, 1) != 1) break; i++; if (*p++ == '\n') break; } fin.nleft = i; return; } /* options: scan option flags, setting flags opt? */ options(argc,argv) int argc; char **argv; { register char c; register int n; char * scan; while (--argc > 0) { scan = *++argv; /* next arg, skipping 1st */ if (*scan == '+') { c = *++scan; /* option code */ scan++; n = getnum(&scan); switch(c) { case 'b': optb = n?n:6; break; case 'e': opte = n?n:72; break; case 'f': optf++; break; case 'i': opti = n?n:2; break; case 'm': optm = n?n:6; break; case 'p': optp = n?n:6; break; case 's': opts++; if (!opte) opte = 72; break; case 't': optt = n?n:72; break; } } else if (ntspec < 2) tspec[ntspec++] = scan; /* save tabspec */ } if (!TSPEC1) TSPEC1 = "--"; /* 1st defaults to 1st line of file */ if (!TSPEC2) TSPEC2 = TSPEC1; /* but 2nd defaults to 1st tabspec */ scantab(TSPEC1,tabin,0); scantab(TSPEC2,tabout,0); return; } /* functions scantab, repetab, arbitab, and getnum are identical to those in tabs(I). filetab is similar, but saves 1st-line read and found flag externally, so that fwrite may use them */ /* scantab: scan 1 tabspec & return tab list for it */ scantab(scan,tabvect,level) char *scan; int tabvect[NTABS], level; { register char c; if (*scan == '-') if ((c = *++scan) == '-') filetab(++scan,tabvect,level); else if (c >= '0' && c <= '9') repetab(scan,tabvect); else if (stdtab(scan,tabvect)) abend("unknown tab code"); else; else arbitab(scan,tabvect); return; } /* repetab: scan and set repetitive tabs, 1+n, 1+2*n, etc */ repetab(scan,tabvect) char *scan; int tabvect[NTABS]; { register int incr, i, tabn; int limit; incr = getnum(&scan); tabn = 1; limit = (maxtab-1)/(incr?incr:1)-1; /* # last actual tab */ if (limit>NTABS-2) limit = NTABS-2; for (i = 0; i<=limit; i++) tabvect[i] = tabn =+ incr; tabvect[i] = 0; return; } /* arbitab: handle list of arbitrary tabs */ arbitab(scan,tabvect) char *scan; int tabvect[NTABS]; { register int i, t, last; char c; last = 0; for (i = 0; i increment, not absolute */ if (t = getnum(&scan)) tabvect[i++] = last =+ t; else abend("illegal increment"); } else { if ((t = getnum(&scan)) > last) tabvect[i++] = last = t; else abend("illegal tabs"); } if (*scan++ != ',') break; } if (last > NCOLS) abend("illegal tabs"); tabvect[i] = 0; return; } /* filetab: copy tabspec from existing file */ filetab(scan,tabvect,level) char *scan; int tabvect[NTABS]; { register int length, i; register char c; char *endspec; /* ptr to blank or colon after tspec*/ char savchar; int fildes; char state; char *temp; if (level) abend("file indirection"); if (*scan == '\0') { /* tabspec was -- by itself, get from 1st line*/ temp = &fin.buffer[0]; if (opts) temp =+ 10; /* ignore 1st 10 chars: SCCS R.L */ for (i = 0; i < CARDSIZ;) card[i++] = *temp++; /* copy to safe place */ length = CARDSIZ; } else { if ((fildes = open(scan,0)) < 0) abend("can't open"); length = read(fildes,card,CARDSIZ); close(fildes); } found = state = 0; scan = 0; for (i = 0; i') { found = 1; goto done; } else state = 5; break; } } done: if (found && scan != 0) { savchar = *endspec; *endspec ='\0'; scantab(scan,tabvect,1); *endspec = savchar; } else scantab("-8",tabvect,1); return; } /* fwrite: write format specification (tabout) as 1st line of file */ /* entry: if tabspec from --file, expects card and found to be set*/ fwrite() { if(TSPEC2[0] == '-' && TSPEC2[1] == '-') if (found) output(card); else output("<:t-8 d:>\n"); else { output("<:t"); output(TSPEC2); output(" d:>\n"); } return; } /* getline: read next line into line, expand tabs into blanks */ /* exit: return -1 on EOF, >= 0 otherwise */ getline(itab) int itab[]; { char c; int i; /* counter for sccs prefix */ int ctab, pctab; register int nextcol; /* logical position (allow BS/CTRL,etc*/ register char *p; if (opts) { /* if SCCS, stash R.L away */ for (i = 0; i <= 9; i++) if ((srelev[i] = getchal()) < 0) return(-1); /* EOF or error */ if (srelev[4] != '.' || srelev[9] != '\t') abend("not SCCS -m"); } nextcol = 1; p = pfirst = line+NCOLS; /* start at middle of workarea */ do { if (fin.nleft-- > 0) c = *fin.nextp++; /* c = getchal() */ else if ((c = getchal()) < 0) /* once per buffer */ break; if (c == '\t') { while ((ctab = *itab) && nextcol >= ctab) itab++; pctab = ctab ? p + (ctab-nextcol) : p+1; nextcol =+ pctab-p; /* adjust column for tab */ while(p < pctab) *p++ = ' '; } else if ((*p++ = c) == '\n') break; if (c >= ' ') nextcol++; /* all normal chars */ else if (c == '\b' || c == ESC) nextcol--; /* ESC+anything or ctrl char = 0-width */ } while (p <= liner); plast = p-1; if (p > liner) abend("line too long"); return(c); } /* getchal: local variant of getchar with stop mode processing: note EOF return is -1 rather than 0 */ getchal() { if (fin.nleft <= 0) { /* make sure output flushed if last char was newline, thus allowing nroff -s or .rd requests, with small overhead */ if (fin.nextp != 0 && *--fin.nextp == '\n') fflush(&fout); fin.nleft = read(fin.fildes,fin.buffer,512); fin.nextp = fin.buffer; } if (fin.nleft-- > 0) return(*fin.nextp++); return(-1); } /* prepend: add blanks to front of line */ prepend(n) int n; { register char *p; p = pfirst; if (pfirst < linel+n) abend("line too long"); while(n--) *--p = ' '; pfirst = p; return; } /* truncate: truncate line to n chars max */ truncate(n) int n; { if (plast > pfirst+n) *(plast = pfirst+n) = '\n'; return; } /* remtrail: delete trailing blanks */ remtrail() { register char *p; p = plast; while(*--p == ' ' && p >= pfirst); *++p = '\n'; plast = p; return; } /* blankout: blank first n chars, iff they are blanks/digits */ blankout(n) int n; { register char *p, *ptemp; char doblank; doblank = 1; ptemp = ((p = pfirst+n-1) '9') && *p != ' ') doblank = 0; if (doblank) for(p = pfirst; p <= ptemp;) *p++ = ' '; return; } /* extend: extend lines to fixed length */ extend(n) int n; { register char *p; register char *ptemp; p = plast; plast = ((ptemp = pfirst+n) < liner)?ptemp:liner-1; ptemp = plast; while (p < ptemp) *p++ = ' '; *p = '\n'; return; } /* movleft: shift line left (remove leading chars) */ movleft(n) int n; { pfirst = ((pfirst =+ n)= *itab) itab++; if (blnkcnt >= n || nextcol == 1) /* always lead blnks */ while((it = *itab) && it <= nextcol+blnkcnt) { *pout++ = '\t'; t = it-nextcol; blnkcnt =- t; nextcol =+ t; itab++; } } nextcol =+ blnkcnt; /* leftover blanks, if any */ while(blnkcnt--) *pout++ = ' '; blnkcnt = 0; *pout++ = c; /* finally, actual input char */ if (c >= ' ') nextcol++; /* normal chars */ else if (c == '\b' || c == ESC) nextcol--; /* ESC-anything or other ctrl chars = 0-width */ } while(c != '\n'); output(outbuf); return; } /* output: write 1 line (terminated by '\0' or '\n') */ output(str1) char *str1; { register char c; register char *str; str = str1; while (c = *str++) { putc(c,&fout); if (c == '\n') break; } return; } /* abend: terminate with error and print diagnostic */ abend(mesg) char *mesg; { int ttydes,ttyold[3]; char *p; if (gtty(ttydes = 2,ttyold)) ttydes = 1; write(ttydes,"reform:",7); p = mesg; while(*p++); write(ttydes,mesg,p-mesg); write(ttydes,"\n",1); exit(1); } /* getnum: scan and convert number, return zero if none found */ getnum(scan1) /* set scan ptr to addr of ending delimeter */ char **scan1; { register int n; register char c, *scan; n = 0; scan = *scan1; while ((c = *scan++) >= '0' && c <= '9') n = n * 10 + c -'0'; *scan1 = --scan; return(n); } /* stdtabs: standard tabs table format: option code letter(s), null, tabs, null */ char stdtabs[] { 'a', 0,1,10,16,36,72,0, /* IBM 370 Assembler */ 'a','2',0,1,10,16,40,72,0, /* IBM Assembler alternative*/ 'c', 0,1,8,12,16,20,55,0, /* COBOL, normal */ 'c','2',0,1,6,10,14,49,0, /* COBOL, crunched*/ 'c','3',0,1,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62,67,0, /* crunched COBOL, many tabs */ 'f', 0,1,7,11,15,19,23,0, /* FORTRAN */ 'p', 0,1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,0, /* PL/I */ 's', 0,1,10,55,0, /* SNOBOL */ 'u', 0,1,12,20,44,0, /* UNIVAC ASM */ 0}; /* stdtab: return tab list for any "canned" tab option. entry: option points to null-terminated option string tabvect points to vector to be filled in exit: return(0) if legal, tabvect filled, ending with zero return(-1) if unknown option */ stdtab(option,tabvect) char option[]; int tabvect[]; { register char *sp; tabvect[0] = 0; sp = stdtabs; while (*sp) { if (equal(option,sp)) { while (*sp++); /* skip to 1st tab value */ while (*tabvect++ = *sp++); /* copy, make int */ return(0); } while(*sp++); /* skip to 1st tab value */ while(*sp++); /* skip over tab list */ } return(-1); } /* equal: string comparison, return 1 if equal, 0 otherwise */ equal(s1,s2) char *s1,*s2; { register char c; while((c = *s1++) == *s2++ && c); if (c == *--s2) return(1); return(0); } t[]; { register char *sp; tabvect[0] = 0; sp = stdtabs; while (*sp) { if (equal(opt-4 "arg count" You typed either too few or too many arguments. -6 "bad date/time" The date/time must be a legitimate date/time in the form "YY[MM[DD[HH[MM[SS]]]]]". The program knows about things like leap years, so be precise. -7 "bad heuristic level" The heuristic level must be a number from 0 to 3. -8 "bad lookahead" The lookahead must be an integer greater than 0. -26 "can't open ..." The file couldn't be opened for reading. Either it doesn't exist or it isn't readable. -42 "format error at record ..." The format of the SCCS file is logically invalid. The error was discovered at the stated record. See if you can find the problem with the prt command. If not, do a "help stuck". -46 "level not allowed with e" You can't specify a level when you're getting with the "e" argument. -47 "level not numeric" You erred in typing a level number. -48 "level too big" You specified a level greater than the highest level for the release, or else one bigger than 9999. -49 "missing file arg" You left the file argument off. -53 "not an SCCS file" The file isn't an SCCS file, Use prt if you don't believe it. -55 "out of space" There's no more dynamic memory left. If you got this from delta, try a smaller lookahead ("l" argument). If you got it somewhere else, better go to "help stuck". -58 "premature eof" The SCCS file ended in a strange place. Its probably a goner. You can try "help stuck", but chances are you're going to have to go to a backup copy. -63 "release not numeric" You erred in typing a release number. -69 "unknown key letter" You typed an illegal argument key letter. -71 "zero release" You can't specify release 0. -75 "Who are you?" Your entry in "/etc/passwd" is messed up. Tell the UNIX system administrator. -83 "not found" No helpful information associated with your argument was found. If you're sure you've got it right, do a "help stuck". -115 "hardware -- " This error is most likely due to an intermittent hardware error. You should report this to your local UNIX support group. immediately, since others may be getting the same error and it is useful to discover a pattern if one exists. After reporting it, if you rerun the command it will probably not recur. If it won't go away contact your PWB counsellor. (If required, a core dump will be produced if the file "dump.core" exists in the current directory.) -stuck First, if you know the value of the system error number (errno), you can either look up a description of it in INTRO(II), or execute "help err" (e.g., if the error number is 1 execute "help err1"). If you don't know the error number, or you don't understand what's going on - Try the following, in order: 1. Make sure the answer isn't in the documentation. We get upset if you call us and it is. 2. Try to write(I) to anyone logged in as "pw" or "pw". 3. Contact your PWB counsellor. 4. File an MR (see PIB-75-02). 5. Go on to something else. 6. Take a nap (after hanging up). When you awake go to step 1. -delta delta [-s] [-n] [-a] [-y] sccsfile [textfile] -get get [-r[.]] [-o] [-c] [-i] [-x] [-k] [-e] [-l[f][]] [-p] [-m] [-s] name ... -admin admin [-d] [-p] [-t] [-n] [-i[] [-r]] [-c] [-f] [-l] ... [-u] ... [-a] ... [-e] ... [-y] [-z] name ... -prt prt [-p [-s]] [-h] [-r] [-d] [-b] [-x] name ... -help help [arg] (When all else fails execute "help stuck".) -what what file ... -201 "corrupted file" The computed hash count of the input SCCS file did not check with the stored hash count. The file may have been damaged since it was last accessed. See your local SCCS maintenance person. -202 "record too big" Internal error. Execute "help stuck". (putr called with len > 255.) -204 "can't read `...'" The named directory exists but isn't readable. Checks its modes with "ls -ld ...". -205 "`...' too long" The pathname is too long. -206 "directory `...' unwritable" The effective user (probably you) doesn't have write permission in the directory. Do a "ls -ld ..." to check the modes. -207 "error ... creating `...'" An unusual error in attempting to create the file. Try "help stuck". (Function xcreat; number is external errno.) -208 "`...' nonexistent" The file does not exist. Check for typos. -209 "`...' unreadable" The file probably exists, but the effective user doesn't have read permission. It is also possible that one or more directories in the path aren't executable. -210 "`...' unwritable" The file exists, but the effective user doesn't have write permission. It is also possible that one or more directories in the path aren't executable. -211 "`...' unreadable or unwritable" The file exists, but the effective user either doesn't have read permission, or write permission, or both. It is also possible that one or more directories in the path aren't executable. -212 "error ... opening `...'" An unusual error occurred while opening the file. Try "help stuck". (Function xopen; number is external errno.) -213 "directory `...' nonexistent" The directory doesn't exist. Check for typos. -215 "writable `...' exists" For safety's sake, SCCS won't overwrite an existing g-file if it's writable. If you don't need the g-file, remove it and rerun the get command. -216 "bad p-file" The p-file has the wrong format. If you have write permission on it you can try to fix it with the editor, or else remove it and do another get with an e argument. -217 "release too big" Release numbers can't be bigger than 9999. -218 "release ... < ... (floor)" Either the release you specified or else the default release is lower than the lowest allowable release (the floor). If you're not sure what's wrong see your SCCS administrator. -219 "release ... > ... (ceiling)" Either the release you specified or else the default release is higher than the highest allowable release (the ceiling). If you're not sure what's wrong see your SCCS administrator. -220 "release ... locked" The release you specified or the default release is locked. Refer questions to your SCCS administrator. -222 "bad range" In a delta list, the two limits of a range of deltas were not in ascending order. -223 "delta list syntax" A list of deltas was syntatically erroneous. The correct syntax is: ::= | , ::= | - ::= | . -224 "invalid release" In a delta list, one of the following errors was made: 1. A release number was less than 1. 2. A release number was greater than the highest release which has a delta. -225 "invalid level" A level specified in a delta list does not exist. -226 "vacant release" A level was omitted in a delta list, but the specified release has no deltas in it. -227 "e not allowed with m" You can't use both the -e and -m arguments on the same get command. -228 "being edited at release ... by `...'" You can't do a get with an -e argument because someone else already did and hasn't made a delta yet. If that someone else is really you, you can regenerate a new file to be edited, if necessary, by using the -k argument. If you want to cancel the reservation entirely, see your SCCS administrator, and tell him/her you want the p-file removed. -229 "... already included" You mentioned the same delta twice with an -i and/or an -x argument. -230 "... already excluded" You mentioned the same delta twice with an -x and/or an -i argument. -231 "internal error in get/enter()" Do a "help stuck". -232 "value after ... arg" You had something after the indicated keyletter argument and you weren't supposed to. -301 "not an SCCS file" A file that you think is an SCCS file does not begin with the characters "s.". -302 "Release p is empty; accessing r.l" No level was specified; the release specified has no deltas. The release and level actually being accessed is r.l. (If the k keyletter was not explicitly or implicitly supplied, the replacement for the %R% and %L% keywords will be r and l, respectively -- not p and 0.) This is not an error, only a warning. -303 "clock set wrong!!!" The time of day is wrong. Contact your local UNIX support group immediately! (Try a "date" command.) (This error is produced whenever the creation date of the newest delta in the SCCS file is newer than the current date. This will happen whenever the date is accidently set wrong. This error will also occur if a delta was created while the clock was set ahead - but less than a year - and has since been corrected. In this case the current time is correct, but the date of the delta is wrong.) -304 "level zero not allowed" You are not allowed to specify level zero because level zero doesn't mean anything. If you want the highest level of a given release, specify the release number without a level. -305 "No id keywords" No SCCS identification keywords were substituted for. You may not have any keywords in the file, in which case you can ignore this warning. If this message came from delta then you just made a delta without any keywords. If this message came from get then the last time you made a delta you changed the lines on which they appeared. It's a little late to be telling you that you messed up the last time you made a delta, but this is the best we can do for now, and it's better than nothing. This isn't an error, only a warning. -306 "Clock may be set wrong!" The time of day may be set wrong. Check the current time with the "date" command. If it is wrong, contact your local UNIX support group immediately! (This message is produced whenever the difference between the current date and the creation date of the newest delta in the SCCS file is greater than one year.) -307 "you are not `...'" Your login name is not the same as the one found in the p-file. You can't remove a delta when a p-file exists, and the name therein is not yours. -308 "you are not `...'" Your login name is not the same as the login name of the person who made the most recent delta. Only the person who made a delta can remove it (when a p-file exists). -309 "sorry" You are not the owner of both the directory containing the sccs file, and the sccs file itself. If a p-file doesn't exist, only the owner of the file and directory can remove a delta. -310 "no delta" The release and level specified is not the release and level of any delta in the sccs file. -311 "sorry" You are not the owner of both the directory containing the sccs file, and the sccs file itself, or you are not the user who made the named delta. -312 "illegal data on line ..." The named line (of the ASCII file) is 5 characters long (not counting the newline), and the fifth character is one of octal 363, 364, or 365. It is illegal to input such data to SCCS. -313 "history too long" A history response can be at most 200 characters long. -322 "you are not `...'" You are not the same person who last did a `get' with an `e' argument. Only the person who did the last `get' with an `e' can make a delta. -323 "read error on standard input" A response from the standard input was solicited and an error occurred. -324 "delta will not propagate" The delta being made is in a release which is lower than the highest numbered release that has deltas. When the SCCS file is gotten at any release higher than the one in which this delta is being inserted, this delta will NOT be applied. This is not an error, only a warning. -325 "more than one link" SCCS files may only have one name (link). This is because the delta program unlinks the old file and then links to the new file. -326 "missing history" If you specify the `-' argument (standard input), you must supply the history on the command line (-y argument). -330 "error ... linking `...' to `...'" An error occurred while linking the first file to the second file. The number is the system error number (see INTRO(II)). If you can't figure out what happened, execute "help stuck". Remember the error number. (Function xlink; number is external errno.) -331 "error ... unlinking `...'" An error occurred while unlinking the file. The number is the system error number (see INTRO(II)). If you can't figure out what happened, execute "help stuck". Remember the error number. (Function xunlink; number is external errno.) -350 "write error" The file which caused the write error is as large as a file can be (currently 1M bytes). -351 "no space!" The file system (on which the file which caused the error is being written) is out of space. Very serious!! Contact someone in your local UNIX Support Group immediately! Also, if you can remove any files please do so. -352 "write error ..." This is probably a transient error. Try again; if it happens again do a "help stuck". Remember the error number. (Function xwrite; number is external errno.) -399 "not authorized to make deltas" Your User ID is not on the list of users who are allowed to add deltas to this file. You can execute "prt -h file" to see who is allowed. See your project administrator to get your login on the list. -410 "missing r" You didn't give an "r" argument. -411 "no level specified" You didn't specify a level. -416 "not the most recent delta" Only the most recent delta (the first one printed by prt) can be removed. The release and level you specified are not the same as those of the most recent delta. -420 "bad starting record" The starting record number (s argument) is not a positive integer. -421 "not an SCCS file" The magic number of the named file is not what it should be. The file is probably not an SCCS file. If you're sure it is, then it has probably been corrupted. -450 "bad ceiling" The ceiling (c argument) is not a positive integer. -451 "bad ceiling" The ceiling (c argument) is either too large or too small. -452 "bad floor" The floor (f argument) is not a positive integer. -453 "bad floor" The floor (f argument) is either too large or too small. -454 "bad r argument" The release is not a positive integer. -455 "bad r argument" The release is either too large or too small. -456 "too many locks" More than 5 l arguments were specified. -457 "bad lock" A lock (l argument) is not a positive integer. -458 "bad lock" A lock (l argument) is either too large or too small. -459 "too many unlocks" More than 5 u arguments were specified. -460 "bad unlock" An unlock (u argument) is not a positive integer. -461 "bad unlock" An unlock (u argument) is either too large or too small. -462 "bad y argument" The release is not a positive integer. -463 "bad y argument" The release is either too large or too small. -464 "key letter twice" A key letter was specified twice. This is probably a typo on your part. -465 "more than one file" Only one file argument is allowed when an i argument is specified. -466 "file exists" The file you are trying to create already exists. -467 "file does not exist" The file to be modified does not exist. -468 "read error" The named file is either not an SCCS file, or a corrupted SCCS file. -469 "Release X wasn't locked" You tried to unlock release X which wasn't locked. This is only a warning. -470 "too many locks" The file has already been locked some number of times. You are trying to add some number of locks which will make the total number of locks more than 5. -471 "description too large" More than 99 characters of description (d argument) were specified. -472 "person too large" More than 13 characters of `person' (p argument) were specified. -473 "type too large" More than 9 charcters of `type' (t argument) were specified. -474 "write error" An error occured while trying to update the file. The system is probably in very bad shape. The file did not get updated correctly. -475 -476 "release X twice" You specified X in two lock or unlock arguments. This is probably a typo on your part. -477 "person not in passwd file" The person to be added (or erased) is not in the system password file. * * icat/ucat messages * -600 "missing account number" You forgot to specify an account number (-a argument). -601 "account number" The account number specified is either non-numeric, or is not four characters long. -602 "bad account number" The account number specified is not numeric. -603 "bad forms value" The forms value specified is not four characters long. -604 "bad forms value" The forms value specified is not numeric. -605 "Bad job class" The job class specified is not an alphabetic. -606 "Bad job name" The job name specified is longer than eight characters. -607 "program `...' not found" The specified program is not in /usr/bin or /bin. -608 "bad location" The specified location is not 47, 49, or 51. -609 "bad runid" The specified run id is longer than 6 characters. -610 "bad page limit" The page limit specified is not numeric. -611 "bad time limit" The time limit specified is not numeric. * * end icat/ucat messages * * * ifetch, ufetch, and extr messages * -803 "missing file arg" You forgot to specify a file argument. -804 "premature eof" In extr, a prnt file ended at a strange place. -805 -806 -807 "format err" In epnch, a pnch file has an invalid format. -808 "Possible errors" The file being processed by extr is not in the proper format - this is usually a result of an ifetch or ufetch failure of some kind. Examine the printout file!! This message is only a warning. -809 "cannot fork - try again" The system process table is temporarily full, wait a while and try again. * * vc messages * -901 "unknown command on line ..." The line given begins with a control character, but the command is not a legal one. -902 "`...' never used" The given keyword name was never used in any replacements. This is only a warning. -903 "`...' never declared" The given keyword name never occured in a `dcl' statement. If you did declare it, check for typos. This is only a warning. -904 "`If' with no matching `end'" There is a missing `end' statement, or an extra `if' statement. -905 "`...' declared twice on line ..." The named keyword has been redeclared on the indicated line. -906 "out of space" A maximum of 40 keywords per invocation of vc are allowed. This limit has been exceeded. -907 "unmatched `:' on line ..." On the given line there is no control character to indicate the end of the keyword name. -908 "keyword name too long on line ..." On the indicated line a keyword name exceeds nine characters. -909 "invalid keyword name on line ..." On the indicated line the keyword name does not start with an alphabetic character, or does not contain only alphanumeric characters. -910 "`end' without matching `if' on line ..." There is an extra `end' statement or a missing `if' statement. -911 "parenthesis error on line ..." A left parenthesis occured with no matching right parenthesis or a parenthesis was found where it was not expected. -912 "invalid operator on line ..." An unrecognized operator was found. The legal operators are `!=', `=', `<', and `>'. -914 "non-numerical value on line ..." On the indicated line an attempt was made to compare a string which contains non-numeric characters with another string using the `<' or `>' operator. -915 "err statement on line ..." The user has put an `err' statement on the given line. -917 "syntax on line ..." The equal sign has been left out of an `asg' statement, or the right side of an `asg' statement is missing. -918 "syntax on line ..." The syntax for the `if' statement on the indicated line is incorrect. An `&' or an `|' occurred in the wrong place, or were not found when they were expected. -919 "syntax on line ..." There is something strange about the indicated line. -920 "`...' never assigned a value" The given keyword name was never used in an assignment statement. This is only a warning. -916 "out of space [line ...]" The indicated line requires too many replacements. Currently, only 32 replacements per line are allowed. -e1 "no space!" The file system you are writing to is out of space. Very serious!! Contact someone in the UNIX Support Group immediately! If you desire to save your latest changes you must, before leaving the editor, do a w command to /tmp/some-unique-file-name If you can remove any files please do so. If you were writing to a non-existent file, a truncated new file has been created. The approximate number of characters written is printed. If useless, remove it. -e2 "no space?" <> blocks left The file system you are writing to may not have enough space to write out this multiple linked file. Very serious!! Contact someone in the UNIX Support Group immediately! If you still desire to write, do another 'w' command. If there is not enough space, your file will be truncated. Therefore, use caution. It may be smart to save your file first by doing a 'w' command to /tmp/some-unique-file-name. If you can remove any files please do so. -e3 ustat: can't chown: System problem. CHOWN or USTAT failed in ED(I). Contact someone in UNIX Support Group immediately. -e4 can't link: Can not remake file name. Your file exists in the directory you were writing to as a funny name. Funny name has the first letter of your file name followed by five numbers. ls -lt on that directory will show it. -570 "UNIX System <> is not configured for <> RJE [to <>]." Send has decided, from the first card of your jobstream, whether you want IBM or UNIVAC RJE. In addition, you may or may not have specified a particular host (158,168,1110). According to the configuration table, /usr/rje/lines, no such connection is provided from this system (/usr/rje/sys). -571 "Aborted." The execution of send/gath has been terminated prematurely. A signal may have been received, a write error may have occurred, the process may have exceeded its core limit, or standard input may have been read too far. -572 "Errors detected. Send anyway?" This question demands an answer (a string of characters terminated by a newline). Anything beginning "y" or "Y" is affirmative and causes the suspect jobstream to be submitted. Otherwise the jobstream is discarded. -573 "Cannot execute queuer." Send has located what it thinks is the proper RJE subsystem for your job but cannot execute the associated queueing program. Please bring this fact to the attention of PWB operations. -574 "Core exceeded." The program has been unable to allocate more storage for keyword definitions. Reduce the number of keywords or the depth of nesting of input sources (both on a global basis). -575 "Cannot create temporary <>." Send writes the collected jobstream into a temporary file created in the "pool" subdirectory of the appropriate RJE subsystem. The pool directory may have been made unwritable to prevent people from adding to a backlog of queued jobs. -576 "Write error - {file too large|no space left|number <>}." Send/gath will abort if it encounters a write error. The first two errors are distinguished, because you may be able to do something about them. Either segment your file into smaller pieces or clean up on disk blocks. Remaining errors are reported by number, as per intro(II). -577 "Hang-up." A hang-up signal has been received (loss of carrier from tty). -578 "Interrupt." An interrupt signal has been received (BREAK or DEL from tty). -579 "Quit signal." A quit signal has been received (FS from tty). -580 "Signal #<>." The process has received an unusual signal, which may indicate hardware problems. The number of the signal is reported. -581 "Line <> of <>, cannot open source <>." The specified input source cannot be opened. If the source is an ordinary file argument, examine the name (which is repeated) for possible typographical errors. Extraneous spaces or tabs are not allowed. If the source is cited on a control line, the -c flag may help. -582 "Line <> of <>, format spec rejected." The line containing the format spec is reproduced following the diagnostic. Either it does not conform to the syntax of fspec(PWB V), or it specifies unreasonable parameters, such as too many tabs or excessive s and m values. -583 "Line <> of <>, bad control line ignored." The bad control line is reproduced following the diagnostic. It may be too long. In -s mode, it may contain non-graphics or undefined tabs. -584 "Line <> of <>, non-graphic deleted." The transformed line is reproduced following the diagnostic. The non-printing ASCII characters whose octal codes are 000-010,013-037,177 are excised, except when they occur within keywords or keyword replacements. -585 "Line <> of <>, undefined tab deleted." The transformed line is reproduced following the diagnostic. Tabs beyond the last position at which they are set by the format spec are excised. See fspec(PWB V) to learn how to specify tab stops. -586 "Line <> of <>, cannot reverse chdir." This diagnostic occurs at the end of included sources which have caused a change of current directory by citing an argument of the form "!chdir <>". It indicates that the current directory cannot be reset to its previous value. -587 "Line <> of <>, cannot run shell (<>)." The shell cannot be run on a series of $ arguments because a syscall (create, pipe or fork) has failed. The file which was to be shelled is reproduced following the diagnostic. This probably indicates a scarcity of system resources. -588 "Line <> of <>, default spec rejected." The rejected format spec is reproduced following the diagnostic. It occurred in an argument of the form ":<>:". Either the spec does not conform to the syntax of fspec(PWB V), or it specifies unreasonable parameters, such as too many tabs or excessive s and m values. -589 "Line <> of <>, cannot chdir <>." It is not possible to execute the change of current directory specified by a "!chdir <>" argument. -590 "Line <> of <>, cannot run command (<>)." The shell cannot be run for a ! argument because a syscall (pipe or fork) has failed. The command which was to be executed is reproduced following the diagnostic. This probably indicates a scarcity of system resources. -591 "Line <> of <>, cannot redefine keyword." An attempt has been made to assign a new value to a keyword which is still active at some source level. The current definition of the keyword is reproduced following the diagnostic. -592 "Line <> of <>, shell exit {type|code} <>." The shell which was invoked to process $ or ! arguments has terminated abnormally (type!=0) or has indicated error status upon exit (code!=0). See wait(II). The shell file or command which was processed is reproduced following the diagnostic. Since many standard UNIX commands (but few PWB commands) return an arbitrary status upon exit, you may want to follow them with an "exit 0", which will suppress the diagnostic. -593 "Line <> of <>, long line detected." Gath has encountered a line which violates the s parameter of the current format specification. The line is reproduced following the diagnostic. -594 "Line <> of <>, long line truncated." The transformed line is reproduced following the diagnostic. Send/gath cannot process lines longer than about 300 bytes. The length is further constrained by the s parameter of the current format specification. If the line is to be included in a jobstream, its length cannot exceed 80 bytes (IBM) or 132 bytes (UNIVAC). -595 "Line <> of <>, illegal card excised." The line which send will not allow to be included in a jobstream is reproduced following the diagnostic. Lines beginning "/*$" are excised from IBM jobs because they are interpreted as commands by HASP/JES2. The beginning of an IBM job is indicated by a line which begins with a "/". UNIVAC runs begin with a line of the form "@RUN ..." or "`run ...", etc. Until the beginning of a jobstream is detected, all lines will be flushed. -596 "Overrun on standard input." For the sake of efficiency, data is read from the input stream in blocks or 512 bytes. Data which is not used up by the program is returned by seeking backwards on file descriptor zero. Unfortunately, one cannot seek on pipes. The input which is being piped to send/gath should not include any arguments of the form "-" or "-:prompt". Neither should it attempt a logical end-of-file "~.". -597 "Cannot <> - only <> {blocks|inodes} free on file system <>." Before it proceeds very far, send checks that there are 1500 blocks and 50 inodes free on the file system of the destination RJE subsystem. If there are not, send aborts. The queuer which send invokes also checks for free space, but it is somewhat more lenient. If you have unneeded files on the full file system, please delete them. -598 "..." These diagnostics are issued by the queueing program which is invoked by send. They should only occur if a programming error violates the interface between the two programs. -599 "<>qer: <>. Try again?" The queuer invoked by send has run into trouble, perhaps temporary. Type "y" and newline to try again, or hit interrupt to cancel this attempt to send. You might contact PWB operations. -send send [-lqy] [158,168,1110] file ... Control lines ("~ file2 ...") include additional files. -gath gath [-hi] file ... Control lines include additional files ("~ file2 ...") or collect the output of a command ("~!command arg ..."). * * Biscus project interface error messages * -120 "line ... of ... - bad format" Report this problem to your local SCCS administrator. In the meantime, specify the full pathname of the SCCS file. If you don't know it you'll just have to wait. -121 "no sccs file for ..." Report this problem to your local SCCS administrator immediately! -err1 error 1 "Not owner and not super-user": Typically this error indicates an attempt to modify a file in some way forbidden except to its owner. It is also returned for attempts by ordinary users to do things allowed only to the super-user. -err2 error 2 "No such file or directory": This error occurs when a file name is specified and the file should exist but doesn't, or when one of the directories in a path name does not exist. -err3 error 3 "No such process": The process whose number was given to signal does not exist, or is already dead. -err4 error 4 "Interrupted system call": An asynchronous signal (such as interrupt or quit), which the user has elected to catch, occurred during a system call. If execution is resumed after processing the signal, it will appear as if the interrupted system call returned this error condition. -err5 error 5 "I/O error": Some physical I/O error occurred during a read or write. This error may in some cases occur on a call following the one to which it actually applies. -err6 error 6 "No such device or address": I/O on a special file refers to a subdevice which does not exist, or beyond the limits of the device. It may also occur when, for example, a tape drive is not dialled in or no disk pack is loaded on a drive. -err7 error 7 "Arg list too long": An argument list longer than 512 bytes (counting the null at the end of each argument) is presented to exec. -err8 error 8 "Exec format error": A request is made to execute a file which, although it has the appropriate permissions, does not start with one of the magic numbers 407 or 410. -err9 error 9 "Bad file number": Either a file descriptor refers to no open file, or a read (resp. write) request is made to a file which is open only for writing (resp. reading). -err10 error 10 "No children": Wait and the process has no living or unwaited-for children. -err11 error 11 "No more processes": In a fork, the system's process table is full and no more processes can for the moment be created. -err12 error 12 "Not enough core": During an exec or break, a program asks for more core than the system is able to supply. This is not a temporary condition; the maximum core size is a system parameter. The error may also occur if the arrangement of text, data, and stack segments is such as to require more than the existing 8 segmentation registers. -err13 error 13 "Permission denied": An attempt was made to access a file in a way forbidden by the protection system. -err15 error 15 "Block device required": A plain file was mentioned where a block device was required, e.g. in mount. -err16 error 16 "Mount device busy": An attempt to mount a device that was already mounted or an attempt was made to dismount a device on which there is an open file or some process's current directory. -err17 error 17 "File exists": An existing file was mentioned in an inappropriate context, e.g. link. -err18 error 18 "Cross-device link": A link to a file on another device was attempted. -err19 error 19 "No such device": An attempt was made to apply an inappropriate system call to a device; e.g. read a write-only device. -err20 error 20 "Not a directory": A non-directory was specified where a directory is required, for example in a path name or as an argument to chdir. -err21 error 21 "Is a directory": An attempt to write on a directory. -err22 error 22 "Invalid argument": Some invalid argument: currently, dismounting a non-mounted device, mentioning an unknown signal in signal, and giving an unknown request in stty to the TIU special file. -err23 error 23 "File table overflow": The system's table of open files is full, and temporarily no more opens can be accepted. -err24 error 24 "Too many open files": Only 15 files can be open per process. -err25 error 25 "Not a typewriter": The file mentioned in stty or gtty is not a typewriter or one of the other devices to which these calls apply. -err26 error 26 "Text file busy": An attempt to execute a pure-procedure program which is currently open for writing (or reading!). Also an attempt to open for writing a pure-procedure program that is being executed. -err27 error 27 "File too large": An attempt to make a file larger than the maximum of 32768 blocks. -err28 error 28 "No space left on device": During a write to an ordinary file, there is no free space left on the device. -err29 error 29 "Seek on pipe": A seek was issued to a pipe. This error should also be issued for other non-seekable devices. -err30 error 30 "Read-only file system": An attempt to modify a file or directory was made on a device mounted read-only. -err31 error 31 "Too many links": An attempt to make more than 127 links to a file. -err32 error 32 "Write on broken pipe": A write on a pipe for which there is no process to read the data. This condition normally generates a signal; the error is returned if the signal is ignored. eek on pipe": A seek was issued to a pipe. This error should also be issued for other non-seekable devices. -err30 error 30 "Read-only file system": An attempt to modify a file or directory was made on a device mounted read-only. -err31 error 31 "Too many links": An attempt to make more than 127 links to a file. -err32 error 32 "Wri# include "../sccshead/sfile.h" char ctlrec__[] "~|^`ctlrec.c 1.1"; /* Determines if arg (ctl) is a control record. Returns non-zero if it is, zero if it isn't. */ ctlrec(ctl,len) register struct Control *ctl; int len; { register int ch; if (len==SIZEOFCONTROL && ((ch=ctl->Cctl)==INS || ch==DEL || ch==END)) return(1); return(0); } y a file or directory was made on a device mounted read-only. -err31 error 31 "Too many links": An attempt to make more than 127 links to a file. -err32 error 32 "Wri# define addtostr(X) if (X) *p++ = X; char delstr_____[] "~|^`delstr.c: 3.2"; deltastr(yesno,reason,type,rel,lev,datetime,person,history) char yesno,reason,type; int rel,lev; int *datetime; char *person, *history; { static char str[256]; register int i; register char *p; p = str; i = 0; addtostr(yesno); addtostr(reason); addtostr(type); copy(stringf("%4d.%-4d%s%-6s", rel,lev,ctime(datetime),person),p); p[33] = p[33+7] = ' '; copy(history,p+33+8); return(str); } a file. -err32 error 32 "Wri#include "../sccshead/sfile.h" #include "../sccshead/sint.h" # define ONEYEAR 31536000L char dodelt__[] "~|^`dodelt.c: 3.14"; /* Routine to process the delta table and to fill in the apply array (set up by doreltab()). For each delta, there is an "Apply" structure. "Adt" is the pseudo date/time of the delta; that is, instead of actual binary date/times, monotonically descending integers are used. The "Acode" is EMPTY = not filled in yet APPLY = delta to be applied NOAPPLY = delta not to be applied Once "Acode" is filled in, it is not overwritten. This makes include/exclude work right. Both include/exclude on a get and deltas which include/exclude are supported by this function, although only the former is available to users. This function also writes the l-file. The second argument is used to determine whether the ``Non-prop'' message should be printed. */ int pseudo, dlfd; char *acklist; int ackrel, acklev, acknowl; long timenow; dodeltab(pkt,prtnprp) register struct Packet *pkt; { register struct Deltab *dt; int wantie; long maxrl; long timediff; register struct Apply *ap; int eod; if (pkt->Pupd) mkdeltab(pkt); maxrl.hiword = 1; maxrl.loword = 0; pseudo = 32767; time(&timenow); eod = rdrec(pkt); dt = pkt->Pibuf.Irecptr; if (eod != 1) { timediff = timenow - dt->Ddatetime; if (timediff < 0) fatal("clock set wrong!!! (303)"); if (timediff > ONEYEAR && pkt->Pverbose&WARNING) msg2("Clock may be set wrong! (306)\n"); } for (; eod!=1 && (dt=pkt->Pibuf.Irecptr)->Drel; eod=rdrec(pkt)) { ap = &pkt->Papply[dt->Drel][dt->Dlev]; switch(dt->Dtype) { case 'U': case 'P': case 'D': if (ap->Acode == APPLY) { applyd(pkt,dt,ap,'I',&maxrl); wantie = 1; continue; } if (ap->Acode == NOAPPLY) { skipd(pkt,dt,ap,'X'); wantie = 0; continue; } if (acklist && dt->Dtype=='U') { ackrel = dt->Drel; acklev = dt->Dlev; acknowl = 0; dolist(pkt,acklist,0); if (acknowl) dt->Dtype = 'P'; } if (dt->Drel < pkt->Prel) { if (dt->Dtype == 'U') { pkt->Punack = 1; if (pkt->Pverbose&UNACK) printf("Non-prop: %d.%d\n", dt->Drel,dt->Dlev); } if (dt->Dtype=='U'||dt->Dtype=='P') { skipd(pkt,dt,ap,dt->Dtype); wantie = 0; continue; } } if (gt(&dt->Drel,&pkt->Prel)) { skipd(pkt,dt,ap,' '); wantie = 0; continue; } /* WARNING!!! When a delta is made after the high-order bit of the time of day turns on (Saturday, November 27, 1999 3 AM), the following inequality will fail. */ if (dt->Ddatetime > pkt->Pcutoff) { skipd(pkt,dt,ap,'C'); wantie = 0; continue; } applyd(pkt,dt,ap,' ',&maxrl); wantie = 1; continue; case 'I': if (wantie && ap->Acode == EMPTY) ap->Acode = APPLY; continue; case 'E': if (wantie && ap->Acode == EMPTY) ap->Acode = NOAPPLY; continue; case 'R': case 'H': case 'C': continue; default: fmterr(pkt); } } if (pkt->Plfile && *pkt->Plfile != 'p') close(dlfd); if (pkt->Plev==0 && pkt->Prel>1 && pkt->Pverbose&RLACCESS) { msg2(stringf("Release %d is empty; accessing %d.%d (302)\n", pkt->Prel,maxrl.hiword,maxrl.loword)); pkt->Prel = maxrl.hiword; pkt->Plev = maxrl.loword; } } applyd(pkt,dt,ap,reason,rlp) register struct Packet *pkt; register struct Deltab *dt; register struct Apply *ap; char reason; int *rlp; { ap->Acode = APPLY; ap->Adt = pseudo--; dlist(pkt,dt,' ',reason); if (!pkt->Pcdt) pkt->Pcdt = dt->Ddatetime; if (pkt->Plev==0 && gt(&dt->Drel,rlp)) { rlp[0] = dt->Drel; rlp[1] = dt->Dlev; } } skipd(pkt,dt,ap,reason) register struct Packet *pkt; register struct Deltab *dt; register struct Apply *ap; char reason; { if (!ap->Acode) ap->Acode = NOAPPLY; ap->Adt = pseudo--; dlist(pkt,dt,'*',reason); } dlist(pkt,dt,a,reason) struct Packet *pkt; register struct Deltab *dt; char a, reason; { static char parsed; register char *p; register int n; if (!pkt->Plfile) return; if (!parsed) { if (*pkt->Plfile != 'p') dlfd = xcreat(auxf(pkt,'l'),0444); else dlfd = 1; parsed = 1; } p = deltastr(a,reason,0,dt->Drel,dt->Dlev,&dt->Ddatetime,dt->Dpgmr, dt->Dhist); p[(n=size(p))-1] = '\n'; xwrite(dlfd,p,n); } fmterr(pkt) struct Packet *pkt; { fatal(stringf("format error at record %d (42)",pkt->Precno)); } t,a,reason) struct Packet *pkt; register struct Deltab *dt; char a, reason; { static char parsed; register char *p; register int n; if (!pkt->Plfile) return; if (!parsed) { if (*pkt->Plfile != 'p') dlfd = xcreat(auxf(pkt,'l'),0444)# include "../sccshead/sfile.h" # include "../sccshead/statbuf.h" # include "../sccshead/sint.h" char dofile___[] "~|^`dofile.c 3.2"; int nfiles; char had_dir; char had_standinp; do_file(p,func) register char *p; int (*func)(); { extern char *fatal_file; char str[SIZEOFPfile]; struct Ibufr ibuf; struct Statbuf statbuf; struct { int inum; char name[14]; char extra; } dir; register char *s; int fd; if (p[0] == '-') { had_standinp = 1; opnl(&ibuf,0,0); while (getl(&ibuf) != 1) { s = ibuf.Irecptr; s[ibuf.Ilen-1] = 0; if (sccsfile(s)) { fatal_file = s; (*func)(s); nfiles++; } } } else if(stat(p,&statbuf) != -1 && (statbuf.flags&IFMT) == IFDIR) { had_dir = 1; fatal_file = p; if((fd=open(p,0)) < 0) fatal("can't read (204)"); read(fd,&dir,16); /* skip "." */ read(fd,&dir,16); /* skip ".." */ while(read(fd,&dir,16) == 16) { if(dir.inum == 0) continue; dir.extra = '\0'; s=stringf("%s/%s",p,dir.name); if(size(s) <= SIZEOFPfile) copy(s,str); else fatal("too long (205)"); if(sccsfile(str)) { fatal_file = str; (*func)(str); nfiles++; } } close(fd); } else { fatal_file = p; (*func)(p); nfiles++; } } sccsfile(file) register char *file; { register int ff, result; int magic[2]; result = (ff=open(file,0)) > 0 && read(ff,magic,4) == 4 && magic[1] == MAGICNO; close(ff); return(result); } .inum == 0) continue; dir.extra = '\0'; s=stringf("%s/%s",p,dir.name); if(size(s) <= SIZEOFPfile) copy#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char dohead__[] "~|^`dohead.c: 3.1"; /* Routine to process the module header. All that's necessary is to slide it into the packet. */ dohead(pkt) register struct Packet *pkt; { register struct Header *hdr; if(rdrec(pkt) == 1) fatal("premature eof (58)"); hdr = pkt->Pibuf.Irecptr; if(hdr->Hmagicno != MAGICNO) fatal("not an SCCS file (53)"); move(hdr,&pkt->Phdr,sizeof(*hdr)); } tringf("%s/%s",p,dir.name); if(size(s) <= SIZEOFPfile) copy# include "../sccshead/sfile.h" char dohist___[] "@(#)dohist.c 3.4"; int peekc; dohist(dt,histstr) struct Deltab *dt; char *histstr; { register char *p, *eoh; int bad, tty[3]; peekc = bad = 0; if (!histstr) { if (gtty(0,tty) >= 0) printf("history? "); eoh = &dt->Dhist[sizeof(dt->Dhist)]; for (p=dt->Dhist; p < eoh && (*p=getpeekc()) != '\n'; p++) { if (*p == '\\' && (peekc=getpeekc()) == '\n') { *p = ' '; peekc = 0; } } if (*p == '\n') *p = 0; else bad = 1; } else if (size(histstr) > sizeof(dt->Dhist)) bad = 1; else copy(histstr,dt->Dhist); if (bad) fatal("history too long (313)"); } getpeekc() { register char c; if (c = peekc) peekc = 0; else c = getchr(); return(c); } tty) >= 0) printf("history? "); eoh = &dt->Dhist[sizeof(dt->Dhist)]; for (p=dt->Dhist; p < eoh && (*p=getpeekc()) != '\n'; p++) { if (*p == '\\' && (peekc=getpeekc()) == '\n') { *p = ' '; peekc = 0; } } if (*p == '\n') *p = 0; else bad = 1; } else#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char dolist_[] "~|^`dolist.c: 3.2"; /* Parses delta list as used by -i/-x args of get, for example. Syntax of list: ::= | , ::= | - ::= | . Delta numbers are checked for validity. For each delta, enter() is called. The caller of dolist() should define his own enter(). Argument "ch" is converted to upper-case and passed on to enter(). This strange arrangement is vestigial. */ struct Range { int Rr1; int Rl1; int Rr2; int Rl2; }; char *extlist; /* used by routines in this file only */ dolist(pkt,list,ch) struct Packet *pkt; char list[], ch; { register int r, l, maxl; struct Range range; ch =+ 'A' - 'a'; extlist = list; while(getrange(pkt,&range)) for(r=range.Rr1; r<=range.Rr2; r++) { maxl = maxlev(pkt,r); for(l=(r==range.Rr1?range.Rl1:1); l<=maxl; l++) if(r == range.Rr2 && l > range.Rl2) continue; else enter(pkt,ch,r,l); } } getrange(pkt,rn) register struct Packet *pkt; register struct Range *rn; { rn->Rr1 = rn->Rl1 = rn->Rr2 = rn->Rl2 = -1; if(*extlist == '\0') return(0); getrl(pkt,&rn->Rr1,&rn->Rl1); if(*extlist == '-') { extlist++; getrl(pkt,&rn->Rr2,&rn->Rl2); if(pkt->Pverbose&DOLIST) printf("%d.%d-%d.%d\n",rn->Rr1,rn->Rl1,rn->Rr2,rn->Rl2); if(!gt(&rn->Rr2,&rn->Rr1)) fatal("bad range (222)"); } else { rn->Rr2 = rn->Rr1; rn->Rl2 = rn->Rl1; if(pkt->Pverbose&DOLIST) printf("%d.%d\n",rn->Rr1,rn->Rl1); } if(*extlist == ',') extlist++; else if(*extlist != '\0') fatal("delta list syntax (223)"); return(1); } getrl(pkt,rp,lp) register struct Packet *pkt; register int *rp, *lp; { *rp = getnum(); if(*rp < 1 || *rp > maxrel(pkt) || *rp > pkt->Prel) fatal("invalid release (224)"); if(*extlist == '.') { extlist++; *lp = getnum(); if(*lp < 1 || *lp > maxlev(pkt,*rp)) fatal("invalid level (225)"); } else if((*lp=maxlev(pkt,*rp)) == 0) fatal("vacant release (226)"); } getnum() { char num[50]; register char *n; for(n=num; *extlist>='0' && *extlist<='9'; extlist++) *n++ = *extlist; if(n == num) fatal("delta list syntax (223)"); *n = '\0'; return(patoi(num)); } { *rp = getnum(); if(*rp < 1 || *rp > maxrel(pkt) || *rp > pkt->Prel) fatal("invalid release (224)"); if(*extlist == '.') { extlist++; *lp = getnum(); if(*lp < 1 || *lp > maxlev(pkt,*rp)) fatal("invalid level (225)"); } else if((*lp=maxlev(pkt,*rp)) == 0) fatal("vacant release (226)"); } getn#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char dor__[] "~|^`dor.c: 3.3"; /* Processes r keyword. Second arg points to char after the r. */ dor(rp,lp,s) int *rp, *lp; register char *s; { char number[5]; register char *num; int i; num = number; i = 4; while(*s != '\0' && *s != '.') { *num++ = *s++; if(--i < 0) fatal("release too big (217)"); } *num = '\0'; if((*rp = patoi(number)) < 0) fatal("release not numeric (63)"); if(*rp == 0) fatal("zero release (71)"); if(*s == '\0') { *lp = -1; return; } ++s; num = number; i = 4; while(*s != '\0') { *num++ = *s++; if(--i < 0) fatal("level too big (48)"); } *num = '\0'; if((*lp = patoi(number)) < 0) fatal("level not numeric (47)"); } ister char *num; int i; num = number; i = 4; while(*s != '\0' && *s != '.') { *num++ = *s++; if(--i < 0) fatal("release too big (217)"); } *num = '\0'; if((*rp = patoi(number)) < 0) fatal("release not numeric (63)"); if(*rp == 0) fatal("zero release (71)"); if(*s =#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char auxf__[] "~|^`auxf.c: 3.3"; /* Figures out names for g-file, l-file, x-file, etc. File Module g-file l-file x-file & rest a/s.m m m l.m a/x.m `File' in above chart is `pkt->Pfile'. Second argument is letter; 0 means module name is wanted. */ auxf(pkt,ch) register struct Packet *pkt; register char ch; { static char auxfile[50]; register char *snp; snp = sname(pkt->Pfile); if (!same(snp,"s.",2)) fatal("not an SCCS file (301)"); switch(ch) { case 0: case 'g': copy(&snp[2],auxfile); break; case 'l': copy(snp,auxfile); auxfile[0] = 'l'; break; default: copy(pkt->Pfile,auxfile); auxfile[snp-pkt->Pfile] = ch; } return(auxfile); } ve chart is `pkt->Pfile'. Second argument is letter; 0 means module name is wanted. */ auxf(pkt,ch) register struct Packet *pkt; register char ch; { static char auxfile[50]; register char *snp; snp = sname(pkt->Pfile); if (!same(snp,"s.",2)) fatal("not an SCCS file (301)")#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char dorelt__[] "~|^`dorelt.c: 3.2"; /* Routine to process the release table. It allocates the pkt->Papply jagged array and writes out a new or modified release table entry. Also, pkt->Plev is set to the highest level of the specified release if it is -1 on entry, and pkt->Prel is set to the default release if it is -1. pkt->Pnoprop is set if the specified release is less than the highest release in the release table. Note that neither dimension of the pkt->Papply array needs a zero subscript, so that space is used for dimension sizes: pkt->Papply[0][0].Adt = number of releases pkt->Papply[r][0].Adt = number of levels in release r pkt->Papply[r] = 0 if no deltas in release r */ doreltab(pkt) register struct Packet *pkt; { register struct Reltab *reltab; struct Reltab nreltab; register int first; int found; first = 1; found = 0; do { if(rdrec(pkt) == 1) break; reltab = pkt->Pibuf.Irecptr; if(!pkt->Papply) { pkt->Papply = alloc(2*(reltab->Rrel+1),1); pkt->Papply[0] = alloc(2,1); pkt->Papply[0][0].Adt = reltab->Rrel; } if(reltab->Rrel) { pkt->Papply[reltab->Rrel] = alloc(sizeof(**pkt->Papply)*(reltab->Rlevs+1),1); pkt->Papply[reltab->Rrel][0].Adt = reltab->Rlevs; } if(first) { first = 0; if(pkt->Prel == -1) { pkt->Prel = pkt->Phdr.Hrdef; if(pkt->Prel == 0) pkt->Prel = reltab->Rrel; if(pkt->Prel == 0) pkt->Prel = 1; } if(pkt->Prel < reltab->Rrel) pkt->Pnoprop = 1; }  if(pkt->Prel == reltab->Rrel) { if(pkt->Plev == -1) pkt->Plev = reltab->Rlevs; else if(pkt->Plev > reltab->Rlevs) fatal("level too big (48)"); reltab->Rlevs++; found = 1; continue; } if(pkt->Prel > reltab->Rrel && !found) { nreltab.Rrel = pkt->Prel; nreltab.Rlevs = 1; wrtrec(pkt,&nreltab,sizeof(*reltab)); if(pkt->Plev == -1) pkt->Plev = 0; else if(pkt->Plev) fatal("level too big (48)"); found = 1; continue; } } while(reltab->Rrel); if (pkt->Pverbose&RLACCESS) printf("%d.%d\n",pkt->Prel,pkt->Plev); wrtrec(pkt,0,0); } rlvalid(pkt,r,l) register struct Packet *pkt; register int r, l; { if(r > 0 && r <= pkt->Papply[0][0].Adt && l > 0 && l <= pkt->Papply[r][0].Adt) return(&pkt->Papply[r][l]); return(0); } maxrel(pkt) register struct Packet *pkt; { return(pkt->Papply[0][0].Adt); } maxlev(pkt,r) register struct Packet *pkt; register int r; { if(pkt->Papply[r] == 0) return(0); return(pkt->Papply[r][0].Adt); } eltab->Rrel); if (pkt->Pve#include "../sccshead/sfile.h" #include "../sccshead/sint.h" # include "../sccshead/statbuf.h" char wrtrec__[] "~|^`wrtrec.c: 3.3"; /* Routine to write out either the current record in the packet (if nrec is zero) or the record specified by nrec and nlen. A record is actually written (and the x-file is only opened) if pkt->Pupd is non-zero. When the current record from the packet is written, pkt->Pwrttn is set non-zero, and further attempts to write it are ignored. When a record is read into the packet, pkt->Pwrttn must be turned off. Call with nrec == 0 and nlen < 0 is signal to flush the buffer. Note that all control records which are not the current record in the packet (i.e., nrec != 0) are assumed to be in the same release and level (a reasonable assumption). In sequences of the form: I or D . . . E I or D . . . The E followed by the I or D are discarded. In sequences of the form: I or D E The I or D and the E are discarded. */ int x_create; wrtrec(pkt,nrec,nlen) register struct Packet *pkt; register struct Control *nrec; register int nlen; { static struct Obufr obf; static struct Control prevctl; static char haveprev, lastiord; struct Statbuf sb; char *xf; if(pkt->Pupd == 0) return; if(!x_create) { stat(pkt->Pfile,&sb); xf = auxf(pkt,'x'); crtr(&obf,xf,sb.flags); chown(xf,(sb.gid<<8)|sb.uid); x_create = 1; haveprev = 0; } if(haveprev) { haveprev = 0; if (ctlrec(nrec,nlen)) { if (nrec->Cctl==lastiord && prevctl.Cctl==END) return; if (nrec->Cctl==END && (prevctl.Cctl==INS || prevctl.Cctl==DEL)) return; } putr(&obf,&prevctl,SIZEOFCONTROL); } if (ctlrec(nrec,nlen)) { move(nrec,&prevctl,SIZEOFCONTROL); haveprev = 1; if(prevctl.Cctl == INS || prevctl.Cctl == DEL) lastiord = prevctl.Cctl; return; } if (nrec) putr(&obf,nrec,nlen); else { if(!pkt->Pwrttn++) putr(&obf,pkt->Pibuf.Irecptr,pkt->Pibuf.Ilen); if (nlen < 0) { flshr(&obf,0); close(obf.Ofildes); } } } xrm(pkt) struct Packet *pkt; { if(x_create) unlink(auxf(pkt,'x')); x_create = 0; } vctl.Cctl==DEL)) return; } putr(&obf,&prevctl,SIZEOFCONTROL); } if (ctlrec(nrec,nlen)) { move(nrec,&prevctl,SIZEOFCONTROL); haveprev = 1; if(prevctl.Cctl == INS || prevctl.Cctl == DEL) lastiord = prevctl.Cctl; return; } if (nrec) putr(&obf,nrec,nlen); else { if(!pkt->Pwrttn++) putr(&obf,pkt->Pibuf.Irecptr,pkt->Pibuf.Ilen); if (nlen < 0) { flshr(&obf,0); close(obf.Ofildes); } } } xrm(pkt) strchar dtcvt__[] "~|^`dtcvt.c: 2.3"; /* Function to convert date in the form "yymmddhhmmss" to standard UNIX time (seconds since Jan. 1, 1970 GMT). Units left off of the right are replaced by their maximum possible values. The function corrects properly for leap year, daylight savings time, offset from Greenwich time, etc. Function returns -1 if bad time is given (i.e., "730229"). */ char *cbp; int timbuf[2]; dtcvt(adt,bdt) char *adt; int bdt[]; { int y, t, d, h, m, s, i; extern int timezone, *localtime(); cbp = adt; if((y=g2()) == -2) y = 99; if(y<70 || y>99) return(-1); if((t=g2()) == -2) t = 12; if(t<1 || t>12) return(-1); if((d=g2()) == -2) d = mosize(y,t); if(d<1 || d>mosize(y,t)) return(-1); if((h=g2()) == -2) h = 23; if(h<0 || h>23) return(-1); if((m=g2()) == -2) m = 59; if(m<0 || m>59) return(-1); if((s=g2()) == -2) s = 59; if(s<0 || s>59) return(-1); timbuf[0] = timbuf[1] = 0; y =+ 1900; for(i=1970; iIfildes = xopen(file,0); buf->Irecptr = buf->Ibuff2 + 2; buf->Iend = buf->Irecptr + 510; buf->Ilen = 510; buf->Ibuff3[1] = -128; buf->Ihcnt = buf->Ihtot = buf->Ihflag = 0; } getr(buf) register struct Ibufr *buf; { register char *p, *q; int *w; int i, n; buf->Irecptr =+ buf->Ilen + !(buf->Ilen & 1); i = 0; while(1) { buf->Ilen = 0; buf->Ilen = *buf->Irecptr + 128; if(buf->Irecptr <= buf->Iend - (buf->Ilen+!(buf->Ilen&1)))  return(++buf->Irecptr); if(i++ == 1) return(1); q = buf->Irecptr; p = buf->Irecptr =- 512; while(q <= buf->Iend) *p++ = *q++; if((n = read(buf->Ifildes,buf->Ibuff2,512)) <= 0) return(1); buf->Iend = buf->Ibuff2 + n - 1; *(buf->Iend + 1) = -128; w = buf->Ibuff2; if(buf->Ihflag == 0) { buf->Ihflag = 1; buf->Ihtot = w[HASHADDR>>1]; w[HASHADDR>>1] = 0; } if(n < 512) buf->Ibuff2[n] = 0; buf->Ihcnt =+ sumr(w,&w[(n&1?n-1:n-2)>>1]); if(n<512 && buf->Ihtot && buf->Ihcnt != buf->Ihtot) fatal("corrupted file (201)"); } } sumr(from,to) register int *from, *to; { register int sum; for (sum=0; from<=to; ) sum =+ *from++; return(sum); } 2,512)) <= 0) return(1); buf->Iend = buf->Ibuff2 + n - 1; *(buf->Iend + 1) = -128; w = buf->Ibuff2; if(buf->Ihflag == 0) { buf->Ihflag = 1; buf->Ihtot = w[HASHADDR>>1]; w[HASHADDR>>1] = 0; } if(n < 512) buf->Ibuff2[n] = 0; buf->Ihcnt =+ sumr(w,&w[(n&1?n-1:n-2)>>1]); if(n<512 && buf->Ihtot && buf->Ihcnt#include "../sccshead/sfile.h" char outbuf_[] "~|^`outbuf.c: 3.1"; /* Bottom level write routines for SCCS files. Usage: struct Obufr ob; ... crtr(&ob,"filename",0666); ... putr(&ob,recaddr,reclen); ... flshr(&ob); Recaddr need not be even, but it will be written to an even address in the file anyhow. Putr automatically computes a hash count for the written file and stores it in address HASHADDR. Second (non-zero) argument to flshr if present suppresses storing of the hash count. This argument must be used for compatibility with Release 1 of SCCS. */ crtr(buf,file,mode) register struct Obufr *buf; char file[]; int mode; { buf->Ofildes = xcreat(file,mode); buf->Obuff1[0] = '\0'; buf->Orecptr = buf->Obuff1 + 1; buf->Oend = buf->Orecptr + 510; buf->Ohcnt = buf->Ohflag = 0; } struct {int *ip;}; putr(buf,rec,len) struct Obufr *buf; char *rec; int len; { register int l; register char *p, *r; int lsave; char *rsave; l = len; p = buf->Orecptr; r = rec; if(l > 255) fatal("record too big (202)"); *p++ = l - 128; if(!(l&1)) l++; while(1) { while(p <= buf->Oend) { if(l-- == 0) { buf->Orecptr = p; return; } *p++ = *r++; } xwrite(buf->Ofildes,p=buf->Obuff1,512); lsave = l; rsave = r; if(buf->Ohflag == 0) { buf->Ohflag = 1; p.ip[HASHADDR>>1] = 0; } r.ip = p.ip + 256; for(l=0; p.ipOhcnt =+ l; l = lsave; r = rsave; p = buf->Obuff1; } } flshr(buf,nohash) struct Obufr *buf; int nohash; { register int n, *p, *q; n = buf->Orecptr - buf->Obuff1; if(n < 512) buf->Obuff1[n] = 0; xwrite(buf->Ofildes,buf->Orecptr=buf->Obuff1,n); p = buf->Obuff1; q = &p[(n&1?n-1:n-2)>>1]; for(n=0; p<=q; p++) n =+ *p; buf->Ohcnt =+ n; if(nohash) return; seek(buf->Ofildes,HASHADDR,0); write(buf->Ofildes,&buf->Ohcnt,2); } r.ip = p.ip + 256; for(l=0; p.ipOhcnt =+ l; l = lsave; r = rsave; p = buf->Obuff1; } } flshr(buf,nohash) struct Obufr *buf; int nohash; { regi#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char permss__[] "~|^`permiss.c: 3.1"; /* Checks for floor, ceiling and locked release, and also for real user on list of users authorized to make deltas. */ permiss(pkt) register struct Packet *pkt; { register int i, uid; if(pkt->Prel < pkt->Phdr.Hfloor) fatal(stringf("release %d < %d (floor) (218)", pkt->Prel,pkt->Phdr.Hfloor)); if(pkt->Phdr.Hceil && pkt->Prel > pkt->Phdr.Hceil) fatal(stringf("release %d > %d (ceiling) (219)",  pkt->Prel,pkt->Phdr.Hceil)); for(i=0; i<5; i++) if(pkt->Prel == pkt->Phdr.Hsw[i]) fatal(stringf("release %d locked (220)",pkt->Prel)); uid = getuid()&0377; for(i=0; i<32; i++) if(pkt->Phdr.Hulist[i] != 0) if((pkt->Phdr.Hulist[uid>>3]&(1<<(uid&7)))==0) fatal("not authorized to make deltas (399)"); else return; } tringf("release %d < %d (floor) (218)", pkt->Prel,pkt->Phdr.Hfloor)); if(pkt->Phdr.Hceil && pkt->Prel > pkt->Phdr.Hceil) fatal(stringf("release %d > %d (ceiling) (219)", #include "../sccshead/sfile.h" #include "../sccshead/sint.h" char rdmod__[] "~|^`rdmod.c: 3.3"; /* Routine to apply deltas. See "The Source Code Control System" (TM75-9152-3). */ readmod(pkt) register struct Packet *pkt; { register struct Control *ctl; register struct Apply *ap; while(rdrec(pkt) != 1) { ctl = pkt->Pibuf.Irecptr; if (!ctlrec(ctl,pkt->Pibuf.Ilen)) { if(pkt->Pkeep == YES) { pkt->Plnno++; return(0); } continue; } if (ctl->Crel > maxrel(pkt) || ctl->Clev > maxlev(pkt,ctl->Crel)) fmterr(pkt); if(ctl->Cctl == END) { if(remq(pkt,ctl)) break; continue; } ap = &pkt->Papply[ctl->Crel][ctl->Clev]; if(ap->Acode == APPLY) { addq(pkt,ctl,ap,ctl->Cctl==INS?YES:NO); continue; } if(ap->Acode == NOAPPLY) { addq(pkt,ctl,ap,ctl->Cctl==INS?NO:NULL); continue; } fmterr(pkt); } if(pkt->Pq) fatal("premature eof (58)"); return(1); } addq(pkt,ctl,ap,keep) struct Packet *pkt; struct Control *ctl; struct Apply *ap; int keep; { register struct Queue *cur, *prev, *q; int dt; dt = ap->Adt; for(cur = &pkt->Pq; cur = (prev=cur)->Qnext;) if(cur->Qdt <= dt) break; prev->Qnext = q = alloc(sizeof(*q)); q->Qnext = cur; q->Qrel = ctl->Crel; q->Qlev = ctl->Clev; q->Qdt = dt; q->Qkeep = keep; setkeep(pkt); } remq(pkt,ctl) register struct Packet *pkt; struct Control *ctl; { register struct Queue *cur, *prev; for(cur = &pkt->Pq; cur = (prev=cur)->Qnext;) if(cur->Qlev == ctl->Clev && cur->Qrel == ctl->Crel) break; if(cur) { prev->Qnext = cur->Qnext; free(cur); setkeep(pkt); return(0); } if(ctl->Crel) fmterr(pkt); return(1); } setkeep(pkt) register struct Packet *pkt; { register struct Queue *q; for(q = &pkt->Pq; q = q->Qnext;) if(q->Qkeep != NULL) { if((pkt->Pkeep=q->Qkeep) == YES) { pkt->Pirel = q->Qrel; pkt->Pilev = q->Qlev; } return; } pkt->Pkeep = NO; } , *prev; for(cur = &pkt->Pq; cur = (prev=cur)->Qnext;) if(cur->Qlev == ctl->Clev && cur->Qrel == ctl->Crel) break; if(cur) { pre#include "../sccshead/sfile.h" #include "../sccshead/sint.h" char rdrec__[] "~|^`rdrec.c: 2.3"; /* Routine to read a record into the packet. The main reason for it is to make sure that pkt->Pwrttn gets turned off, and to increment pkt->Precno. */ rdrec(pkt) register struct Packet *pkt; { register int n; if(pkt->Pwrttn==0) wrtrec(pkt,0,0); if((n=getr(&pkt->Pibuf)) != 1) { pkt->Precno++; pkt->Pwrttn = 0; } return(n); } r->Qlev == ctl->Clev && cur->Qrel == ctl->Crel) break; if(cur) { pre# include "../sccshead/sfile.h" # include "../sccshead/sint.h" char rwpfl__[] "~|^`rwpfile.c: 3.4"; /* Reads and writes p-file, which is used to pass info from get to delta. See call of stringf below for format of file. Users doing simultaneous gets with e args on the same SCCS file can interfere with one another. However, the worst thing that can happen is that one of them will be inconvenienced when he executes delta, and the cost of avoiding this is too high. */ wrtpfile(f,r) char f[]; int r; { register int fd; register char *p; fd = xcreat(f,0444); p = stringf("%d %s\n",r,getlnam()); xwrite(fd,p,size(p)-1); close(fd); } char bpf[] "bad p-file (216)"; rdpfile(f,rp,un) char f[], un[]; int *rp; { register int fd, i; register char *p; char s[65], *name; fd = xopen(f,0); if ((i=read(fd,s,64))<=0) fatal(bpf); close(fd); p = s; p[i] = 0; for (; *p != ' '; p++) if (*p == 0) fatal(bpf); *p = 0; if ((*rp=patoi(s)) == -1) fatal(bpf); ++p; while (*p++ == ' ') ; name = --p; for (; *p != '\n'; p++) if (*p == 0) fatal(bpf); *p = 0; if ((p-name)>SZLNAM) fatal(bpf); copy(name,un); } ckpfile(file) register char *file; { int r; char un[SZLNAM]; if(exists(file)) { rdpfile(file,&r,un); fatal(stringf("being edited at release %d by `%s' (228)", r,un)); } } ad(fd,s,64))<=0) fatal(bpf); close(fd); p = s; p[i] = 0; for (; *p != ' '; p++) if (*p == 0) fatal(bpf); *p = 0; if ((*rp=patoi(s)) == -1) fatal(bpf); ++p; while (*p++ == ' ') ; name = --p# include "../sccshead/sfile.h" # include "../sccshead/sint.h" # include "../sccshead/statbuf.h" char sinit____[] "~|^`sinit.c 3.2"; /* Does initialization for sccs files and packet. */ sinit(pkt,file,linktest) register struct Packet *pkt; register char *file; { struct Statbuf sb; zero(pkt,sizeof(*pkt)); if (size(file) > SIZEOFPfile) fatal("too long (205)"); copy(file,pkt->Pfile); opnr(&pkt->Pibuf,pkt->Pfile); if (linktest) { fstat(pkt->Pibuf.Ifildes,&sb); if (sb.nlinks > 1) fatal("more than one link (325)"); } pkt->Pwrttn = 1; } "../sccshead/sint.h" # include "../sccshead/statbuf.h" char sinit____[] "~|^`sinit.c 3.2"; /* Does initialization for sccs files and packet. */ sinit(pkt,file,linktest) register struct Packet *pkt; register char *file; { struct Statbuf sb; zero(pkt,sizeof(*pkt)); if (size(file) > SIZEOFPfile) fatal("too long (205)"); copy(file,pkt->Pfile); opnr(&pkt->Pibuf,pkt->Pfile); if (linktest) { fstat(pkt->Pibuf.Ifildes,&sb); if (sb.nlinks > 1) fatal("more than# define HADA had[('a'-'a')] # define HADB had[('b'-'a')] # define HADC had[('c'-'a')] # define HADD had[('d'-'a')] # define HADE had[('e'-'a')] # define HADF had[('f'-'a')] # define HADG had[('g'-'a')] # define HADH had[('h'-'a')] # define HADI had[('i'-'a')] # define HADJ had[('j'-'a')] # define HADK had[('k'-'a')] # define HADL had[('l'-'a')] # define HADM had[('m'-'a')] # define HADN had[('n'-'a')] # define HADO had[('o'-'a')] # define HADP had[('p'-'a')] # define HADQ had[('q'-'a')] # define HADR had[('r'-'a')] # define HADS had[('s'-'a')] # define HADT had[('t'-'a')] # define HADU had[('u'-'a')] # define HADV had[('v'-'a')] # define HADW had[('w'-'a')] # define HADX had[('x'-'a')] # define HADY had[('y'-'a')] # define HADZ had[('z'-'a')] ADI had[('i'-'a')] # define HADJ had[('j'-'a')] # define HADK had[('k'-'a')] # define HADL had[('l'-'a')] # define HADM had[('m'-'a')] # define HADN had[('n'-'a')] # define HADO had[('o'-'a')] # define HADP had[('p'-'a')] # define HADQ had[('q'-'a')] # define HADR had[(# define EPERM 1 # define ENOENT 2 # define ESRCH 3 # define EINTR 4 # define EIO 5 # define ENXIO 6 # define E2BIG 7 # define ENOEXEC 8 # define EBADF 9 # define ECHILD 10 # define EAGAIN 11 # define ENOMEM 12 # define EACCES 13 # define ENOTBLK 15 # define EBUSY 16 # define EEXIST 17 # define EXDEV 18 # define ENODEV 19 # define ENOTDIR 20 # define EISDIR 21 # define EINVAL 22 # define ENFILE 23 # define EMFILE 24 # define ENOTTY 25 # define ETXTBSY 26 # define EFBIG 27 # define ENOSPC 28 # define ESPIPE 29 # define EROFS 30 fine ENOENT 2 # define ESRCH 3 # define EINTR 4 # define EIO 5 # define ENXIO 6 # define E2BIG 7 # define ENOEXEC 8 # define EBADF 9 # define ECHILD 10 # define EAGAIN 11 # define ENOMEM 12 # define EACCES 13 # define ENOTBLK 15 # define EBUSY 16 # define EEXIST 17 # define EXDEV 18 # define ENODEV 19 # define ENOTDIR 20 # define EISDIR 21 # define EINVAL 22 # define ENFILE 23 # define EMFILE 24 # define ENOTTY 25 # define ETXTBSY 26 # define EFBIG 27 # define ENOSPC 28 # define ESPIPE # /* SCCS File Structures (3.6 76/11/24 10:24:35) See sccsfile(V). */ struct Header { int Hmagicno; char Htype[10]; char Hpers[14]; char Hdesc[100]; int Hfloor; int Hceil; int Hsw[5]; int Hrdef; char Hulist[32]; char Hexpand[50]; int Hash; }; #define MAGICNO (7) #define HASHADDR (226) struct Reltab { int Rrel; int Rlevs; }; struct Deltab { int Drel; int Dlev; char Dtype; /*'D': delta,'P','U': non-prop,'I': incl,'E': excl */ char Dfill; /* Used to be option letter */ long Ddatetime; char Dpgmr[8]; char Dhist[200]; }; struct Control { int Crel; int Clev; char Cctl; /* -11: ins, -12: del, -13: end */ }; #define SIZEOFCONTROL (5) #define INS (-11) #define DEL (-12) #define END (-13) struct Line { char Lline [256]; }; /* Structure for use with buffered I/O routines opnl, opnr, getl and getr. */ struct Ibufr { int Ifildes; char *Irecptr; char *Iend; char Ibuff1[256]; char Ibuff2[512]; char Ibuff3[2]; int Ilen; int Ihflag; int Ihcnt; int Ihtot; }; /* Structure for use with buffered I/O routines crtr, crtl, putl, putr, flshr and buflsh. */ struct Obufr { int Ofildes; char *Orecptr; char *Oend; char Obuff1[512]; int Ohflag; int Ohcnt; }; /* * structure to access an * integer in bytes */ struct { char lobyte; char hibyte; }; /* * structure to access an integer */ struct { int integ; }; /* * structure to access a long as integers */ struct { int hiword; int loword; }; /* Structure for referencing pieces of localtime(). */ struct Time { int Tseconds; int Tminutes; int Thours; int Tday_month; int Tmonth; int Tyear; int Tday_week; int Tday_year; int Tflag; }; *Oend; char Obuff1[512]; int Ohflag; int Ohcnt; }; /* * structure to access an * integer in bytes */ struct { char lobyte; char hibyte; }; /* * structure to access an integer */ struct { int integ; }; /* * structure to access a long as integers */ struct { int hiword; int loword; }; /* Structure for referencing pieces of localtime(). # /* Structure for use with stat(II) and fstat(II). (2.4) */ struct Statbuf { char minor; char major; int inumber; int flags; char nlinks; char uid; char gid; char size0; int size1; int addr[8]; int actime[2]; int modtime[2]; }; /* flags */ #define IALLOC (0100000) /* file is used */ #define IFMT (060000) /* type of file */ #define IFDIR (040000) /* directory */ #define IFCHR (020000) /* character special */ #define IFBLK (060000) /* block special, 0 is regular */ #define ILARG (010000) /* large addressing algorithm */ #define ISUID (04000) /* set user id on execution */ #define ISGID (02000) /* set group id on execution */ #define ISVTX (01000) /* save swapped text even after use */ #define IREAD (0400) /* read, write, execute permissions */ #define IWRITE (0200) #define IEXEC (0100) IFMT (060000) /* type of file */ #define IFDIR (040000) /* directory */ #define IFCHR (020000) /* character special */ #define IFBLK (060000) /* block special, 0 is regular */ #define ILARG /* SCCS Internal Structures (used by get and delta). (3.11) */ struct Apply { int Adt; /* pseudo date-time */ int Acode; /* APPLY, NOAPPLY or EMPTY */ }; #define APPLY (1) #define NOAPPLY (-1) #define EMPTY (0) struct Queue { struct Queue *Qnext; int Qrel; /* release */ int Qlev; /* level */ int Qdt; /* pseudo date-time */ int Qkeep; /* keep switch setting */ }; #define YES (1) #define NO (-1) #define NULL (0) #define SIZEOFPfile (50) struct Packet { char Pfile[SIZEOFPfile]; /* file name containing module */ /* Note: the order of the next two words can not___ be changed! This is because the release and level together are treated as a long. */ int Prel; /* specified release (-1 = not spec.) */ int Plev; /* specified level (-1 = not spec.)*/ char Pverbose; /* verbose flags (see #define's below) */ char Pupd; /* update flag (!0 = update mode) */ long Pcutoff; /* specified cutoff date-time */ struct Header Phdr; /* header from module */ int Plnno; /* line number of current line */ int Precno; /* record number of current rec */ char Pwrttn; /* written flag (!0 = written) */ char Pkeep; /* keep switch for readmod() */ struct Apply **Papply; /* ptr to apply array */ struct Queue *Pq; /* ptr to control queue */ struct Ibufr Pibuf; /* input buffer */ long Pcdt; /* date/time of newest applied delta */ char *Plfile; /* 0 = no l-file; else ptr to l arg */ char Punack; /* !0 if unacknowledged non-prop deltas */ char Pnoprop; /* !0 if new delta is to be non-prop */ int Pirel; /* rel which inserted current rec */ int Pilev; /* lev which inserted current rec */ }; /* Masks for Pverbose */ # define RLACCESS (1) # define NLINES (2) # define DOLIST (4) # define UNACK (8) # define NEWRL (16) # define WARNING (32) /* size of login name */ # define SZLNAM (7) /* date/time of newest applied delta */ char *Plfile; /* 0 = no l-file; else ptr to l arg */ char Punack; /* !0 if unacknowledged non-prop deltas */ char Pnoprop; /* !0struct buf { int fildes; /* File descriptor */ int nleft; /* Chars left in buffer */ char *nextp; /* Ptr to next character */ char buff[512]; /* The buffer */ }; bufread(iobuf,addr,cnt) struct buf *iobuf; char *addr; int cnt; { register struct buf *p; register int n, i; int t, rc; /* SCCS ID INFO */ "~|^`bufrd.c 1.3 %O%"; /* SCCS ID INFO */ rc = 0; p = iobuf; n = cnt; while ((t = (i = p->nleft)-n)<=0) { move(p->nextp,addr,i); n =- i; rc =+ i; addr =+ i; if((p->nleft = read(p->fildes,p->nextp = iobuf->buff,512))<0) return(-1); else if (p->nleft==0) return(rc); } if (n) { move(p->nextp,addr,n); p->nleft = t; p->nextp =+ n; rc =+ n; } return(rc); } brinit(iobuf,fd) struct buf *iobuf; int fd; { register struct buf *p; p = iobuf; p->fildes = fd; p->nleft = 0; p->nextp = p->buff; } 3 %O%"; /* SCCS ID INFO */ rc = 0; p = iobuf; n = cnt; while ((t = (i = p->nleft)-n)<=0) { move(p->nextp,addr,i); n =- i; rc =+ i; addr =+ i; if((p->nleft = read(p->fildesstruct buf { int fildes; int nfree; char *nextp; char buff[512]; }; bufwrite(iobuf,addr,cnt) struct buf *iobuf; char *addr; int cnt; { register struct buf *p; register int n,i; /* SCCS ID INFO */ "~|^`bufwrt.c 1.2 %O%"; /* SCCS ID INFO */ p = iobuf; n = cnt; while (n > (i=p->nfree)) { move(addr,p->nextp,i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { register struct buf *p; p=iobuf; xwrite(p->fildes,p->buff,512-p->nfree); p->nfree = 512; p->nextp = p->buff; } bwcrt(iobuf,fd,file,mode) struct buf *iobuf; int fd; char *file; int mode; { register struct buf *p; if (fd<0) fd = xcreat(file,mode); p=iobuf; p->fildes = fd; p->nfree = 512; p->nextp = p->buff; } i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { regchar *_cat_[] "~|^`cat.c 1.2"; cat(dest,source) char *dest,*source; { register int i; register char *d,*s; int n; n = nargs()-1; d = dest; for (i=0; ifildes = fd; p->nfree = 512; p->nextp = p->buff; } i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { regchar cindex___[] "~|^`cindex.c 1.1"; /* Returns offset of char c in string s. Returns -1 if c is not in s. */ cindex(s, c) char *s, c; { register char *r, a; a = c; r = s; while (*r) if (*r++ == a) return(r-s-1); return(-1); } t(file,mode); p=iobuf; p->fildes = fd; p->nfree = 512; p->nextp = p->buff; } i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { regchar clean_____[] "~|^`clean.c: 2.1"; /* Default clean_up routine for fatal and setsig. */ clean_up() { } */ cindex(s, c) char *s, c; { register char *r, a; a = c; r = s; while (*r) if (*r++ == a) return(r-s-1); return(-1); } t(file,mode); p=iobuf; p->fildes = fd; p->nfree = 512; p->nextp = p->buff; } i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { regchar copy_____[] "~|^`copy.c: 2.2"; /* Copy first string to second; no overflow checking. Returns pointer to null in new string. */ copy(a,b) register char *a, *b; { while(*b++ = *a++); return(--b); } ) return(r-s-1); return(-1); } t(file,mode); p=iobuf; p->fildes = fd; p->nfree = 512; p->nextp = p->buff; } i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { regchar dblgtr_____[] "~|^`dblgtr.c: 2.1"; /* Compares two 32-bit integers (a,b) and (c,d). High-order bits of b and d are relevant. Returns 1 if (a,b) > (c,d); otherwise returns 0. Useful for comparing times. */ dblgtr(a,b,c,d) int *a, *b, *c, *d; { if(a > c) return(1); if(a == c) return(b > d); return(0); } ; } i); addr =+ i; n =- i; p->nfree = 0; bwflush(p); } if (n) { move(addr,p->nextp,n); p->nfree =- n; p->nextp =+ n; } return(cnt); } bwflush(iobuf) struct buf *iobuf; { reg# include "../sccshead/statbuf.h" # define DIRSIZ 50 char dname_____[] "~|^`dname.c 2.3"; /* Returns directory name containing a file. Returns "." if current directory; handles root correctly. */ dname(p) char p[]; { static char dir[DIRSIZ]; struct Statbuf sb; register char *c; register int s; if((s=size(p)) > DIRSIZ) fatal("`",p,"' too long (205)"); copy(p,dir); for(c=dir+s-2; c>dir; c--) if(*c == '/') { *c = '\0'; if (stat(dir,&sb)== -1) continue; if ((sb.flags&IFMT)==IFDIR) return(dir); } if(*c == '/') *(c+1) = '\0'; else copy(".",dir); return(dir); } .c 2.3"; /* Returns directory name containing a file. Returns "." if current directory; handles root correctly. */ dname(p) char p[]; { static char dir[DIRSIZ]; struct Statbuf sb; register char *c; register int s; if((s=size(p)) > DIRSIZ) fatal("`",p,"' too long (205)"); copy(p,dir); for(c=dir+s-2; c>dir; c--) if(*c == '/') { *c = '\0'; if (stat(dir,&sb)== -1) continue; if ((sb.flags&IFMT)==IFDIR) retchar dsize_____[] "~|^`dsize.c: 2.1"; /* Transforms byte+integer file size as returned by stat(II) and fstat(II) to double precision number. */ double dsize(size0,size1) char size0; int size1; { return(32.*1024.*(((size0&0377)<<1)+((size1>>15)&1))+(size1&077777)); } ister char *c; register int s; if((s=size(p)) > DIRSIZ) fatal("`",p,"' too long (205)"); copy(p,dir); for(c=dir+s-2; c>dir; c--) if(*c == '/') { *c = '\0'; if (stat(dir,&sb)== -1) continue; if ((sb.flags&IFMT)==IFDIR) ret# char alloc__[] "~|^`alloc.c: 1.2"; /* Alloc/free based on those in C library at one time. Also, zero() zeroes memory (first arg must be on word boundary) and freeall() frees all memory allocated. Second arg to alloc() if present causes allocated memory to be zeroed. For documentation see alloc(III) dated 3/1/74. */ #define logical char * struct fb { logical size; char *next; }; int freelist[] { 0, -1, }; logical slop 2; logical frstbrk; alloc(asize,z) logical asize, z; { register logical size; register logical np; register logical cp; if((size = asize) == 0) return(0); size =+ 3; size =& ~01; for(;;) { cp = freelist; while((np = cp->next) != -1) { if(np->size>=size) { if(size+slop >= np->size) cp->next = np->next; else { cp = cp->next = np+size; cp->size = np->size - size; cp->next = np->next; np->size = size; } if(nargs()==2) return(zero(&np->next,size-2)); else return(&np->next); } cp = np; } asize = size<1024? 1024: size; if((cp = sbrk(asize)) == -1) fatal("out of space (55)"); if(frstbrk == 0) frstbrk = cp; cp->size = asize; free(&cp->next); } } free(aptr) char *aptr; { register logical ptr; register logical cp; register logical np; ptr = aptr-2; cp = freelist; while((np = cp->next) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->next = ptr; } freeall() { brk(frstbrk); freelist[0] = frstbrk = 0; freelist[1] = -1; } zero(x,b) int *x, b; { register int *p, *w; w = x + ((b+1)>>1); for(p=x; pnext) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->nexchar equal_____[] "~|^`equal.c: 2.2"; /* Compares 2 strings. Returns 1 if equal, 0 if not. */ equal(a,b) char *a, *b; { register char *x, *y; x = a; y = b; while (*x == *y++) if (*x++ == 0) return(1); return(0); } gical np; ptr = aptr-2; cp = freelist; while((np = cp->next) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->nexchar gt_____[] "~|^`gt.c: 3.1"; /* Compares two longs. */ gt(l1,l2) register long *l1, *l2; { return(*l1 > *l2); } b; { register char *x, *y; x = a; y = b; while (*x == *y++) if (*x++ == 0) return(1); return(0); } gical np; ptr = aptr-2; cp = freelist; while((np = cp->next) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->nex#include "../sccshead/statbuf.h" char exists__[] "~|^`exists.c: 2.1"; /* Returns "flags" word if file exists; otherwise 0. */ exists(f) char f[]; { struct Statbuf sb; if(stat(f,&sb) == -1) return(0); else return(sb.flags); } ; ptr = aptr-2; cp = freelist; while((np = cp->next) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->nexchar exit1_____[] "~|^`exit1.c: 2.1"; /* Default exit1 routine (called by exit2). */ exit1(code) int code; { exit(code); } exists(f) char f[]; { struct Statbuf sb; if(stat(f,&sb) == -1) return(0); else return(sb.flags); } ; ptr = aptr-2; cp = freelist; while((np = cp->next) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->nexchar exit2_____[] "~|^`exit2.c: 2.1"; /* Default exit2 routine (called by fatal). */ exit2(code) int code; { exit1(code); } exists(f) char f[]; { struct Statbuf sb; if(stat(f,&sb) == -1) return(0); else return(sb.flags); } ; ptr = aptr-2; cp = freelist; while((np = cp->next) < ptr) cp = np; if(ptr+ptr->size == np) { ptr->size =+ np->size; ptr->next = np->next; np = ptr; } else ptr->next = np; if(cp+cp->size == ptr) { cp->size =+ ptr->size; cp->next = ptr->next; } else cp->nexchar fatal_____[] "~|^`fatal.c: 2.3"; /* Routine to handle fatal errors. Prints args on file descriptor 2. External "fatal_file" if non-zero should point to "current" file name; it is printed before each message. Routine terminates by calling clean_up and exit2; user of fatal should define own clean_up if cleaning up is necessary on termination. */ char *fatal_file; fatal(a,b,c,d) char *a, *b, *c, *d; { register int n; /* * Kludge for fatal when being called from signal * (one argument which is the signal number). * It should be impossible for good strings to get * loaded at locations 1-3 (except, possibly, for I-D sep.) */ if (a > 3) { n = nargs(); if(n > 0) { write(2,"ERROR",5); if(fatal_file) { write(2," [",2); write(2,fatal_file,size(fatal_file)-1); write(2,"]",1); } write(2,": ",2); write(2,a,size(a)-1); } if(n > 1) write(2,b,size(b)-1); if(n > 2) write(2,c,size(c)-1); if(n > 3) write(2,d,size(d)-1); if(n > 0) write(2,"\n",1); } clean_up(); exit2(1); } l number). * It should be impossible for good strings to get * loaded at locations 1-3 (except, possibly, for I-D sep.) */ if (a > 3) { n = nargs(); if(n > 0) { write(2,"ERROR",5); if(fatal_file) { write(2," [",2); write(2,fatal_file,size(fatal_file)-1); write(2,"]",1); } write(2,": ",2); write(2,a,size(a)-1); } if(n > 1) write(2,b,size(b)-1); if(n > 2) write(2,c,size(c)-1); if(n > 3) write(2,d,size(d)-1); if(n > 0) write(2,"\n",1); } clean_up(); echar getchr_____[] "~|^`getchr.c: 2.2"; /* Like getchar(), but non-bufferring. */ getchr() { char c; if(read(0,&c,1) == 1) return(c); else fatal("read error on standard input (323)"); } "ERROR",5); if(fatal_file) { write(2," [",2); write(2,fatal_file,size(fatal_file)-1); write(2,"]",1); } write(2,": ",2); write(2,a,size(a)-1); } if(n > 1) write(2,b,size(b)-1); if(n > 2) write(2,c,size(c)-1); if(n > 3) write(2,d,size(d)-1); if(n > 0) write(2,"\n",1); } clean_up(); e#include "../sccshead/sfile.h" char getl____[] "~|^`getl.c: 2.7"; /* Routine to open a file for input. */ opnl(buf,file,fd) struct Ibufr *buf; char file[]; int fd; { if(nargs() == 3) buf->Ifildes = fd; else buf->Ifildes = xopen(file,0); buf->Irecptr = buf->Ibuff2; buf->Iend = buf->Irecptr + 511; buf->Ilen = 512; return(0); } /* Routine to read a line from a "normal" ASCII file; that is, a file in which lines are terminated with newlines. Returns 1 on a read error; otherwise returns address of the line. Address is also in buf->Irecptr. Length (including newline) is in buf->Ilen. */ getl(buf) struct Ibufr *buf; { register char *p, *q; register int n; int i, r; p = buf->Irecptr =+ buf->Ilen; i = 0; while(1) { while(p <= buf->Iend) if(*p++ == '\n') { buf->Ilen = p - buf->Irecptr; return(buf->Irecptr); } if(i++ == 1) return(1); q = buf->Irecptr; p = buf->Irecptr =- buf->Iend-buf->Ibuff2+1; while(q <= buf->Iend) *p++ = *q++; buf->Iend = buf->Ibuff2 - 1; do { r = 512 - (buf->Iend - buf->Ibuff2 + 1); n = read(buf->Ifildes,buf->Iend+1,r); buf->Iend =+ n; } while(n > 0 && n != r && *buf->Iend != '\n'); if(buf->Iend < buf->Ibuff2) return(1); } } ->Ilen; i = 0; while(1) { while(p <= buf->Iend) if(*p++ == '\n') { buf->Ilen = p - buf->Irecptr; return(buf->Irecptr); } if(i++ == 1) return(1); q = buf->Irecptr; p = buf->Irecptr =- buf->Iend-buf->Ibuff2+1; while(q <= buf->Iend) *p++ = *q++; buf->Iend = buf->Ibuff2 - 1; char getldr_____[] "~|^`getldr.c: 2.2"; /* Gets login directory. Argument is optional, if not present the real user ID is used. Note that if the argument is present it must be an integer. Note also assumption about position of directory field in password file. */ getldir(auid) int auid; { char pw[200]; static int ouid; static char ldir[33]; register int i,uid; register char *cp; if (nargs()==0) uid = getuid()&0377; else uid = auid; if (ouid!=uid || ouid==0) { if (getpw(uid,pw)) return(0); cp = pw; while (*cp++ != ':') ; /* login name */ while (*cp++ != ':') ; /* passwd */ while (*cp++ != ':') ; /* user ID */ while (*cp++ != ':') ; /* comment */ for (i=0; i<32; i++) { if ((ldir[i] = *cp)=='\0' || *cp==':') break; cp++; } ldir[i] = '\0'; } return(ldir); } ; { char pw[200]; static int ouid; static char ldir[33]; register int i,uid; register char *cp; if (nargs()==0) uid = getuid()&0377; else uid = auid; if (ouid!=uid || ouid==0) { if (getpw(uid,pw)) return(0); char getlnm_____[] "~|^`getlnm.c: 2.2"; /* Gets login name. Argument is optional, if not present the real user ID is used. Note that if the argument is present it must be an integer. */ getlnam(auid) int auid; { char pw[200]; static int ouid; static char lnam[9]; register int i,uid; if (nargs()==0) uid = getuid()&0377; else uid = auid; if (ouid!=uid || ouid==0) { if (getpw(uid,pw)) copy(stringf("%d",uid),lnam); else { for (i=0; i<8; i++) if ((lnam[i] = pw[i])==':') break; lnam[i] = '\0'; } ouid = uid; } return(lnam); } /* Gets login name. Argument is optional, if not present the real user ID is used. Note that if the argument is present it must be an integer. */ getlnam(auid) int auid; { char pw[200]; static int ouid; static char lnam[9]; register int i,uid; if (nargs()==0) uid = getuid()&0377; else uid = auid; if (ouid!=uid || ouid==0) { if (getpw(uid,pw)) copy(stringf("%d",uid),lnam); else { for (i=0; i<8; i++) if ((lnam[i] = pw[i])==':') break; lnam[i] = '\0'char msg2_____[] "~|^`msg2.c: 2.1"; /* Concatenates args and writes them to file descriptor 2. Caller must supply newline if desired. */ msg2(a,b,c,d) char a[], b[], c[], d[]; { register int n; n = nargs(); if(n > 0) write(2,a,size(a)-1); if(n > 1) write(2,b,size(b)-1); if(n > 2) write(2,c,size(c)-1); if(n > 3) write(2,d,size(d)-1); } if (ouid!=uid || ouid==0) { if (getpw(uid,pw)) copy(stringf("%d",uid),lnam); else { for (i=0; i<8; i++) if ((lnam[i] = pw[i])==':') break; lnam[i] = '\0'char patoi_____[] "~|^`patoi.c: 2.1"; /* Function to convert ascii string to integer. Converts positive numbers only. Returns -1 if non-numeric character encountered. */ patoi(b) char *b; { register int i; register char *a; a = b; i = 0; while(*a >= '0' && *a <= '9') i = 10 * i + *a++ - '0'; if(*a) return(-1); return(i); } -1); } if (ouid!=uid || ouid==0) { if (getpw(uid,pw)) copy(stringf("%d",uid),lnam); else { for (i=0; i<8; i++) if ((lnam[i] = pw[i])==':') break; lnam[i] = '\0'/ C library -- putchar / modified by L Wehr for R haight to accomodate stringf .globl _putchar,_flush .globl _fout .globl _stout _putchar: mov r5,-(sp) mov sp,r5 mov _stout,r0 beq 1f cmp _stout,_stout+2 jhis 2f movb 4(r5),(r0)+ clrb (r0) mov r0,_stout br 2f 1: mov _fout+4,r0 bne 1f jsr pc,fl mov _fout+4,r0 1: movb 4(r5),(r0)+ beq 1f inc _fout+4 dec _fout+2 bgt 1f jsr pc,fl 1: 2: mov 4(r5),r0 mov (sp)+,r5 rts pc _flush: mov r5,-(sp) mov sp,r5 jsr pc,fl mov (sp)+,r5 rts pc fl: mov _fout+4,r0 beq 1f sub $_fout+6,r0 mov r0,0f mov _fout,r0 bne 2f inc r0 2: sys 0; 9f .data 9: sys write; _fout+6; 0:.. .text 1: mov $_fout+6,_fout+4 mov $512.,_fout+2 cmp _fout,$2 bhi 1f mov $1,_fout+2 1: rts pc .bss _fout: .=.+518. _stout: .=.+4 / stout[0]: the current string pointer, / stout[1]: the address of the end of the string. _fout+4 dec _fout+2 bgt 1f jsr pc,fl 1: 2: mov 4(r5),r0 mov (sp)+,r5 rts pc _flush: mov r5,-(sp) mov sp,r5 jsr pc,fl mov (sp)+,r5 rts pc #include "../sccshead/sfile.h" char putl____[] "~|^`putl.c: 4.1"; /* Routine to create and open a file for output. */ crtl(buf,file,mode,fd) struct Obufr *buf; char file[]; int mode, fd; { if(nargs() == 4) buf->Ofildes = fd; else buf->Ofildes = xcreat(file,mode); buf->Orecptr = buf->Obuff1; buf->Oend = buf->Orecptr + 511; return(0); } /* Routine to write a line to a "normal" ASCII file. Second argument must point to a newline-terminated string. */ putl(buf,rec) struct Obufr *buf; char *rec; {  register char *p, *r, *e; p = buf->Orecptr; e = buf->Oend; r = rec; while(1) { while(p <= e) if((*p++ = *r++) == '\n') { buf->Orecptr = p; return(0); } xwrite(buf->Ofildes,p=buf->Obuff1,512); } } /* Routine to dump output buffer. Must be called if putl is used. */ flshl(buf) struct Obufr *buf; { register int n; n = buf->Orecptr - buf->Obuff1; xwrite(buf->Ofildes,buf->Orecptr=buf->Obuff1,n); return(0); } terminated string. */ putl(buf,rec) struct Obufr *buf; char *rec; { # define PWLDSZ 16 # define PWLDF "/usr/pw/ldf" /* * Returns a pointer to the character string representing pw's * login directory. This string is kept in /usr/pw/ldf. */ char *pwld___ "~|^`pwldir.c 1.1"; pwldir() { register int i, j; register char *p; static char dir[PWLDSZ]; if ((i=open(PWLDF,0))<0) return(0); if ((j=read(i,p=dir,PWLDSZ))<0) return(0); close(i); for (i=0; *p++!='\n' && ++i<=j; ); *--p = '\0'; return(dir); } ated string. */ putl(buf,rec) struct Obufr *buf; char *rec; { # include "../sccshead/statbuf.h" char remove_____[] "~|^`remove.c 1.1"; /* remove (unlink): write permission in directories is required (either implicity - owner == effuid, or explicitly) Calls xunlink(). */ remove(file) char *file; { register int m; struct Statbuf buf; char *d; d = dname(file); if(stat(d,&buf) == -1) fatal("directory `",d,"' nonexistent (213)"); m = buf.flags; chmod(d,m|(IWRITE|IEXEC)); xunlink(file); chmod(d,m); } tring. */ putl(buf,rec) struct Obufr *buf; char *rec; { # include "../sccshead/statbuf.h" char rename_____[] "~|^`rename.c 1.3"; /* rename (unlink/link): write permission in directories is required (either implicity - owner == effuid, or explicitly) Calls xlink() and xunlink(). */ rename(oldname,newname) char *oldname, *newname; { register int mo; int mn; struct Statbuf buf; char *dold, *dnew; dold = dname(oldname); dnew = dname(newname); if(stat(dold,&buf) == -1) fatal("directory `",dold,"' nonexistent (213)"); mo = buf.flags; if(stat(dnew,&buf) == -1) fatal("directory `",dnew,"' nonexistent (213)"); mn = buf.flags; chmod(dold,mo|(IWRITE|IEXEC)); chmod(dnew,mn|(IWRITE|IEXEC)); /* Just in case the newname is already being used, remove it if it is there. */ unlink(newname); xlink(oldname,newname); xunlink(oldname); chmod(dold,mo); chmod(dnew,mn); } uf buf; char *dold, *dnew; dold = dname(oldname); dnew = dname(newname); if(stat(dold,&buf) == -1) fatal("directory `",dold,"' nonexistent (213)"); mo = buf.flags; if(stat(dnew,&bufchar same_____[] "~|^`same.c: 2.1"; /* Compares 1st n characters of strings a and b. Returns 1 is equal, 0 if not. Both a and b must be at least of length n. */ same(a,b,n) char a[], b[]; int n; { register int i; for(i=0; i 0) { signal(6,0); abort(); } exit2(1); } ror", "Memory fault", "Bad system call", 0, "Alarm clock" }; setsig(h,i,q) int h, i, q; { extern int setsig1(); register int j, n; if(signal(1,1) == 0) signal(1,h); if(signal(2,1) == 0) signal(2,i); if(signal(3,1) == 0) signal(3,q)# include "../sccshead/errnos.h" char xwrt_____[] "~|^`xwrite.c 1.1"; /* * Interface to write(II) which handles all error conditions. */ xwrite(fildes,buffer,nbytes) char *buffer; { extern int errno; register int n; if (nbytes>0 && (n=write(fildes,buffer,nbytes))!=nbytes) if (errno==EFBIG) fatal("write error (350)"); else if (errno==ENOSPC) fatal("no space! (351)"); else fatal(stringf("write error %d (352)",errno)); } l(1,h); if(signal(2,1) == 0) signal(2,i); if(signal(3,1) == 0) signal(3,q)char size_____[] "~|^`size.c: 2.1"; /* Returns size (counting null byte) of arg string. */ size(s) char s[]; { register int i; i = 0; while(s[i++]); return(i); } char *buffer; { extern int errno; register int n; if (nbytes>0 && (n=write(fildes,buffer,nbytes))!=nbytes) if (errno==EFBIG) fatal("write error (350)"); else if (errno==ENOSPC) fatal("no space! (351)"); else fatal(stringf("write error %d (352)",errno)); } l(1,h); if(signal(2,1) == 0) signal(2,i); if(signal(3,1) == 0) signal(3,q)char sname_____[] "~|^`sname.c: 2.1"; /* Returns pointer to "simple" name of path name; that is, pointer to first character after last "/". If no slashes, returns pointer to first char of arg. */ sname(s) char *s; { register char *p; for(p=s; *p; p++) if(*p == '/') s = p + 1; return(s); } ) fatal("write error (350)"); else if (errno==ENOSPC) fatal("no space! (351)"); else fatal(stringf("write error %d (352)",errno)); } l(1,h); if(signal(2,1) == 0) signal(2,i); if(signal(3,1) == 0) signal(3,q)char xstring[160]; stringf(f,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18, a19,a20,a21) { extern char *stout[2]; /* stout is for strings as fout is for files */ stout[0] = xstring; /* reroutes putchar() */ stout[1] = xstring + sizeof xstring - 1; printf(f,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14, a15,a16,a17,a18,a19,a20,a21); stout[0] = stout[1] = 0; return(xstring); } e error %d (352)",errno)); } l(1,h); if(signal(2,1) == 0) signal(2,i); if(signal(3,1) == 0) signal(3,q)char substr___[] "~|^`substr.c 1.1"; /* Sets aresult to be the value of as starting at origin and alen characters long. Note: The copying of as to aresult stops if either the specified number (alen) characters have been copied, or if the end of as is found. */ substr(as, aresult, origin, alen) char *as, *aresult; int origin, alen; { register char *s, *result; register int len; s = as + origin; result = aresult; len = alen; ++len; while (--len && (*result++ = *s++)) ; aresult[alen]= '\0'; return(aresult); } ~|^`substr.c 1.1"; /* Sets aresult to be the value of as starting at origin and alen characters long. Note: The copying of as to aresult stops if either the specified number (alen) characters have been copied, or if the end of as is found. */ substr(as, aresult, origin, alen) char *as, *aresult; int origin, alen; { register char *s, *result; register int len; s = as + origin; result = aresult; len = alen; ++len; while (--len && (*result++ = *s++)) ; aresult[alen]= '\0'; r# include "../sccshead/errnos.h" # include "../sccshead/statbuf.h" char xcreat_____[] "~|^`xcreat.c: 2.5"; /* "Sensible" creat: write permission in directory is required (either implicity - owner == effuid, or explicitly) in all cases, and created file is guaranteed to have specified mode and be owned by effective user. */ xcreat(name,mode) char name[]; int mode; { register int fd, m; extern int errno; struct Statbuf buf; register char *d; d = dname(name); if(stat(d,&buf) == -1) fatal("directory `",d,"' nonexistent (213)"); m = buf.flags; chmod(d,m|(IWRITE|IEXEC)); if(unlink(name) != -1 || errno == ENOENT) fd=creat(name,mode); else fd = -1; chmod(d,m); if (fd >= 0) return(fd); if(errno == EACCES) fatal("directory `",d,"' unwritable (206)"); else if (errno == ENOSPC) fatal("no space! (351)"); fatal(stringf("error %d creating `%s' (207)",errno,name)); } ter int fd, m; extern int errno; struct Statbuf buf; register char *d; d = dname(name); if(stat(d,&buf) == -1) fatal("directorchar xlink__[] "~|^`xlink.c 1.3"; /* Interface to link(II) which handles all error conditions. */ xlink(f1,f2) { extern errno; if (link(f1,f2)) fatal(stringf("error %d linking `%s' to `%s' (330)",errno,f2,f1)); } /* Interface to unlink(II) which handles all error conditions. */ xunlink(f) { extern errno; if (unlink(f)) fatal(stringf("error %d unlinking `%s' (331)",errno,f)); } xtern int errno; struct Statbuf buf; register char *d; d = dname(name); if(stat(d,&buf) == -1) fatal("directorchar xopen_____[] "~|^`xopen.c: 2.2"; /* Interface to open(II) which differentiates among the various open errors. */ xopen(name,mode) char name[]; int mode; { register int fd; extern int errno; if((fd=open(name,mode)) >= 0) return(fd); if(errno == 2) fatal("`",name,"' nonexistent (208)"); if(errno == 13) { if(mode == 0) fatal("`",name,"' unreadable (209)"); if(mode == 1) fatal("`",name,"' unwritable (210)"); fatal("`",name,"' unreadable or unwritable (211)"); } fatal(stringf("error %d opening `%s' (212)",errno,name)); } 2.2"; /* Interface to open(II) which differentiates among the various open errors. */ xopen(name,mode) char name[]; int mode; { register int fd; extern int errno; if((fd=open(name,mode)) >= 0) return(fd); if(errno == 2) fatal("`",name,"' nonexistent (208)"); if(errno == 13) { if(mode == 0) fatal("`",name,"' unreadable (209)"); if(mode == 1) fatal("`",name,"' unwritable (210)"); fatal("`",name,"' unreadable or unwritable (211)"); } fatal(stringf("error %d open# include "../sccshead/errnos.h" char xpipe__[] "~|^`xpipe.c 1.1"; xpipe(t) int *t; { extern int errno; if (pipe(t)==0) return; fatal(stringf("pipe error %d",errno)); } t fd; extern int errno; if((fd=open(name,mode)) >= 0) return(fd); if(errno == 2) fatal("`",name,"' nonexistent (208)"); if(errno == 13) { if(mode == 0) fatal("`",name,"' unreadable (209)"); if(mode == 1) fatal("`",name,"' unwritable (210)"); fatal("`",name,"' unreadable or unwritable (211)"); } fatal(stringf("error %d open