#include "Bdef.h"

int Shyp_br(ctxt, scope, rsrc, csrc)
BLACSCONTEXT  *ctxt;
char  scope;
int  rsrc;
int  csrc;
{
   void Ssend2d00();
   void Srecv2d00();

   int msgid;
   int relnode, bit, rdest, cdest, Np;
   int info, rbufid;

   scope = Mlowcase(scope);
   switch(scope)
   {
   case 'r':
      Np = ctxt->npcol;
      for (bit=2; bit < Np; bit <<= 1);
      if (bit^Np) return(NPOW2);  /* not a power of 2 */
      msgid = Mrid(ctxt);
      relnode = ctxt->mycol ^ csrc;

      Srecv2d00(ctxt, msgid);
/*
    *    Free send buffer, send from receive buff
 */
      rbufid = pvm_getrbuf();
      info = pvm_freebuf(pvm_setsbuf(rbufid));
      Mpvmerror(info, "pvm_freebuf", __LINE__, __FILE__);
      for(bit=1; (bit^Np); bit <<= 1)
         if (bit > relnode)
            Ssend2d00(ctxt, ctxt->myrow, ctxt->mycol^bit, msgid);
      break;
   case 'c':
      Np = ctxt->nprow;
      for (bit=2; bit < Np; bit <<= 1);
      if (bit^Np) return(NPOW2);  /* not a power of 2 */
      msgid = Mcid(ctxt);
      relnode = ctxt->myrow ^ rsrc;

      Srecv2d00(ctxt, msgid);
/*
    *    Free send buffer, send from receive buff
 */
      rbufid = pvm_getrbuf();
      info = pvm_freebuf(pvm_setsbuf(rbufid));
      Mpvmerror(info, "pvm_freebuf", __LINE__, __FILE__);
      for(bit=1; (bit^Np); bit <<= 1)
         if (bit > relnode)
            Ssend2d00(ctxt, ctxt->myrow^bit, ctxt->mycol, msgid);
      break;
   case 'a':
      Np = ctxt->Ng;
      for (bit=2; bit < Np; bit <<= 1);
      if (bit^Np) return(NPOW2);  /* not a power of 2 */
      bit = Mvkpnum(ctxt, rsrc, csrc);
      msgid = Maid(ctxt);
      relnode = ctxt->vIam ^ bit;

      Srecv2d00(ctxt, msgid);
/*
    *    Free send buffer, send from receive buff
 */
      rbufid = pvm_getrbuf();
      info = pvm_freebuf(pvm_setsbuf(rbufid));
      Mpvmerror(info, "pvm_freebuf", __LINE__, __FILE__);
      for(bit=1; (Np^bit); bit <<= 1)
      {
         if (bit > relnode)
         {
            Mvpcoord(ctxt, ctxt->vIam ^ bit, rdest, cdest);
            Ssend2d00(ctxt, rdest, cdest, msgid);
         }
      }
      break;
   default:
      return(BADSCP);
   }
   pvm_setrbuf(rbufid);  /* restore buffer state */

   return(0);
}
