




    Conv ...  convert a Unix object file to a DEC object file

Often one wishes to combine the computational  power  of  F4P  or
assembler  with  the  I/O flexibility of C or the system routines
that exist in AS.  Conv is a program that  will  convert  a  file
produced by the Unix assembler or loader into an object file that
can be re-linked with DEC style linker to obtain a hybrid output.

Useage is very simple for the most part.  One utters

        & conv-c-f4p [switches] file

and the program will take  file.o  (file.out  if  file.o  doesn't
exist  and  file  itself  if  neither  are  present)  and makes a
file.obj.  This file.obj can be linked  with  LINKER  (note  that
linkr or the Princeton linkr will not work with the output due to
conv's full utilization of the DEC obj standard).

The difficult part in the usage  on  conv  is  understanding  the
implications  of converting a Unix module to a Dec standard modu-
le.  The first crucial point invloves the  understanding  of  the
TEXT,  DATA,  and  BSS sections of the output of AS and LD.  Conv
makes each of these three sections a PSECT, with the Local,  Con-
catenate  and  Relocatable atributes set. For the TEXT psect, SHR
and INS are set.  Data has PRV set and INS clear. BSS has the BSS
attribute  set.   A  fourth PSECT is also generated with absolute
global references.

The default attributes may be changed by use of switches  descri-
bed below.

The  second  point  to  consider  when converting a module is the
.COMM statement of AS.  Comm generates an "undefined" global with
a value.  If the value is undefined at LD time (and if the proper
switches are set) LD will allocate enough BSS space for  the  ob-
ject.   As LINKER does not provide such a capability, CONV allows
for the specification of the disposal of such objects.  The  user
may specify whether he want the symbols to 1) be declared as sim-
ple undefined global symbols or 2) be made into overlay psects of
with  the specified name and approbriate attributes.  The typical
course is to supply LD with the -d switch and therefore be rid of
such  problems.   However,  there  are cases that this is not the
appropriate action.

A third concern is the use  of  the  symbols  _end,  _edata,  and
_etext.   Unfortunatly,  these are resolved by LD's conception of
the world and therefore  are not accurate when the module is  run
through  LINKER.  Therefore, one should not use these symbols and
should exercise caution when using the c routine SBRK which  uses
_end.

Finally, there is the issue of symbols.  Unix format allows eight
characters of the full ascii character set (more or  less).   Dec
standard  allows  six characters of the RAD50 set.  Conv maps the
first six characters of the Unix name to the Rad50 set as best it
can.   It  converts  to  one  case  only (which is upper or lower










depending on how you look at it).  Also there is  a  switch  that
controls the disposition of the character '_' to a user specified
character (or no character whatsoever).

Two more points... the title is the file name, and the version id
is the date.




























































                         Switch summary

      -p switch forces all commons to become psects.

      -s switch forces all commons to symbols.

         No switch causes the program to pause and ask
         Unix symbol blurfff common?
      to which the user should respond "p" to make it a psect and
      anything else to make it a undefined global symbol.

      -t:at1:at2:at3:at4: ... :atn
         This causes the text  psect  attributes  to  be  set  as
      specified.  Attributes include shr, sharable, data, reloca-
      table, private, prv, global, gbl,  absolute,  concentenate,
      overlay,  ovr,  bss,  and any unique abriviation of all the
      above.

      -b:at1:at2:at3:at4: ... :atn
         This is for the BSS psects as for the TEXT psect.

      -c:at1:at2:at3:at4: ... :atn      Attributes   for   common
      psects.

      -d:at1:at2:at3:at4: ... :atn    Attributes for data psect.

      -l This switch causes  c-type  symbols  to  be  suppressed.
      C-type symbols are defined to mean 1) symbols starting with
      'L' and 2) symbols that start with '~' other than  register
      defines.

      -x Causes all non-global symbols to be supressed.

      -f Causes the character "_" (and "~") to be replaced by the
      character "u" when convertng symbol names.  The default (no
      f switch) is to simply eliminate the letters,

      -f:c Causes  the characters "_" and "~" to be output as "c"
      when converting symbol names.



























                               Apendix A
              Example of calling Fortran from a C program

      1) Command File
      macro -ns callf.m11
      cc -r callpi.c
      mv a.out callpi.o
      conv -p -l -f callpi.o
      f4p -c cpi.f4p
      linker callpi.obj callf.obj cpi.obj  -l
























































      2) callpi.c

      main()
      {
              int     v[3];
              double  pi;
              extern cpi();
              int     n;

              oti();  /* initilize the fortran system */
              callf(cpi,&n,&pi,0);
              printf("After %d iterations, pi = %.17f ",n,pi);
              v[0]=2;
              v[1] = &n;
              v[2] = &pi;
              cllfv(cpi,v);
              printf("After %d iterations, pi = %.17f ",n,pi);
              exit(0);
      }















































      3) cpi.f4p
              subroutine ucpi(n,pi)
              real*8  pi,s,t,x,y,z
              n= 0
              s= .5
              t= 2.
              x= 1.
              y= sqrt(2.)/2.
      98      if(x.eq.y)  goto 99
              s= s+ t*(x-y)*(x-y)/4.
              t= t*2
              z= (x+y)/2.
              y= sqrt(x*y)
              n= n+1
              x= z
              goto 98
      99      pi= 2*x*x/(1-s)
      c       write(6,97)n,pi
      c97     format('after ',i,' iterations, pi =',d)
              return
              end













































      4) callf.m11

              .title  callfort

              .psect  $code1,lcl,con,ins,shr
              This file helps a c-routine call a f4p routine.

              Use is

                      callf(func, &arg1, &arg2, &arg3, ... &argn, 0)
                      /* all the addr's better be non-zero */

              Where func is presumably a f4p func, and arg's are
              pointers to things that f4p knows about.

              What this thing does is to set up a r5 pointer of the
              type that Fort wants, and jsr to the Fort routine.

              Notice that the func name itself is not!! passed.

              Also consider the f4p long integer conventions.

              Callf assumes that you are using the "-f" switch in
              conv without an arg


              .globl  ucallf

      ucallf: mov     sp,r0
              mov     r5,-(sp)
              mov     r4,-(sp)
              mov     r3,-(sp)
              mov     r2,-(sp)
              tst     (r0)+           ;past caller's address
              mov     r0,r5           ;now we get pointer to actual list
              mov     (r5),r1         ;save func
              clr     (r5)
              tst     (r0)+           ;and point to start of args
      1$:     tst     (r0)+           ;zero => done
              beq     2$
              inc     (r5)
              br      1$              ;kick count, and loop
      2$:     jsr     pc,(r1)         ;call the func
              mov     (sp)+,r2
              mov     (sp)+,r3
              mov     (sp)+,r4
              mov     (sp)+,r5        ;contex restored, so
              setd            ; return in double mode
              setl            ;and long
              rts     pc              ;go home
















              .globl  ucllfv          ;"smart user vector "

              This is a short routine that allows the hacker to
              make a short call to the Fort routine.


      ucllfv: mov     2(sp),r0
              mov     4(sp),r1        ;and the vector address
              mov     r5,-(sp)
              mov     r4,-(sp)
              mov     r3,-(sp)
              mov     r2,-(sp)
              mov     r1,r5
              jsr     pc,@r0          ;call that fort func
              mov     (sp)+,r2
              mov     (sp)+,r3
              mov     (sp)+,r4
              mov     (sp)+,r5        ;restore world
              setd
              setl            ;and long
              rts     pc


              .globl  oti$,uoti
      uoti:   jmp     oti$

              .end







































                              Appendix 2
                       Example of F4P calling C

      1) Command File
      macro callc.m11 -ns
      cc -O cctime.c -c
      conv -p -l cctime.o
      rm cctime.o
      ld -r -u _ctime -u _time -lc -l
      conv -p -l a.out
      rm a.out
      mv a.obj ctime.obj
      f4p date.f4p callc.obj  ctime.obj cctime.obj





















































      2) Date.f4p
              dimension       i(2)
              dimension       idate(20)

              external        cctime,time,ctime,ct1

              call    callc(time,i)
              call    callc(cctime,ctime,idate,i)
              write(6,9)idate
       9      format(20a)
              do 10 j=1,20
              idate(j)=0
       10     continue
              call    callcv(ct1,ctime,time,idate,i)
              write(6,9)idate
              stop
              end

















































      3) Cctime.f4p

              /*
               * This is a demo routine that copys the vector
               * returned by the func (ctime) to the buffer
               *
               * Forrest W Howard, Jr.
               */
      cctime(f,d,v)
      char    *d;
      int     (*f)();
      {
              register char *a,*b;

              a = (*f)(v);
              b=d;
              while(*b++ = *a++);
              return;
      }

      ct1(v)
      char    **v;
      {
              register (*f)();
              register char   *to,*fr;

              f = v[3];
              (*f)(v[5]);
              f= v[2];
              fr = (*f)(v[5]);
              to = v[4];
              while(*to++ = *fr++);
              return;
      }
































      3) Callc.m11
              .psect  $code1,lcl,con,ins,shr

              .title  callc
              .ident  /fwh01/

              Callc is a linkage routine to call a c routine from
              f4p.  It is very stupid itself... it simply aranges for the
              args to be stacked, and then jsr's off to the c prog.

              An example of use is:

                      callc(cfunc, arg1, arg2, arg3, ....)

              cfunc(a1, a2, a3, ..... )
              int     *arg1;
              int     arg2[];
              double  *arg3;
                  ....

              The important thing to note is lvalues are passed.
              thus all the c variables must be of type ptr to... .

              No value is returnable from a call routine.
              Therfore, clobber an l-value if you care.

              Note that longs are passed backwards in f4p.
              Thus the long int  1,,2 is passed
                      2
                      1
              Just beware.

              forrest w howard jr, 4/27/76

              .globl  callc
      callc:  setd
              setl
              mov     r5,r4
              mov     sp,r2           ;need to save sp
              mov     (r4)+,r3        ;get count
              bic      177400,r3      ;no guarantee of h.o.b.
              mov     r4,r1           ;and copy r4 for end check
              asl     r3              ;adjust to words
              add     r3,r4           ;and kick it
      1$:     mov     -(r4),-(sp)     ;copy it
              cmp     r4,r1
              bhi     1$              ;loop till copied
              jsr     pc,@(sp)+       ;top element is caller
              mov     r2,sp           ;restore sp (and flush)
              rts     pc              ;and return with glee
















              .globl  callcv          ;and callcv


              Callcv is a cross between the above, and execv of
              unix c library fame.
              What is passes is the arg vector to the c program, to
              be massaged by knowledgeble users.

                      callcv(cfunc,arg1, arg2, arg3, ....)

              cfunc(x)
              ???     **x;

              See the f4p book for more description



      callcv:
              setd
              setl
              mov     r5,-(sp)        ;sav the vector
              jsr     pc,@2(r5)       ;and call that c code
              tst     (sp)+           ;be nice to world
              rts     pc              ;and quit


              .end


































