Beispiel #1
0
/*
 * ppb_MS_loop()
 *
 * Execute a microseq loop
 *
 */
int
ppb_MS_loop(device_t bus, device_t dev, struct ppb_microseq *prolog,
            struct ppb_microseq *body, struct ppb_microseq *epilog,
            int iter, int *ret)
{
    struct ppb_microseq loop_microseq[] = {
        MS_CALL(0),			/* execute prolog */

        MS_SET(MS_UNKNOWN),		/* set size of transfer */
        /* loop: */
        MS_CALL(0),			/* execute body */
        MS_DBRA(-1 /* loop: */),

        MS_CALL(0),			/* execute epilog */
        MS_RET(0)
    };

    /* initialize the structure */
    loop_microseq[0].arg[0].p = (void *)prolog;
    loop_microseq[1].arg[0].i = iter;
    loop_microseq[2].arg[0].p = (void *)body;
    loop_microseq[4].arg[0].p = (void *)epilog;

    /* execute the loop */
    return (ppb_MS_microseq(bus, dev, loop_microseq, ret));
}
static char
vpoio_select(struct vpoio_data *vpo, int initiator, int target)
{
	device_t ppbus = device_get_parent(vpo->vpo_dev);
	int ret;

	struct ppb_microseq select_microseq[] = {

		/* parameter list
		 */
		#define SELECT_TARGET		MS_PARAM(0, 1, MS_TYP_INT)
		#define SELECT_INITIATOR	MS_PARAM(3, 1, MS_TYP_INT)

		/* send the select command to the drive */
		MS_DASS(MS_UNKNOWN),
		MS_CASS(H_nAUTO | H_nSELIN |  H_INIT | H_STROBE),
		MS_CASS( H_AUTO | H_nSELIN |  H_INIT | H_STROBE),
		MS_DASS(MS_UNKNOWN),
		MS_CASS( H_AUTO | H_nSELIN | H_nINIT | H_STROBE),

		/* now, wait until the drive is ready */
		MS_SET(VP0_SELTMO),
/* loop: */	MS_BRSET(H_ACK, 2 /* ready */),
		MS_DBRA(-2 /* loop */),
/* error: */	MS_RET(1),
/* ready: */	MS_RET(0)
	};

	/* initialize the select microsequence */
	ppb_MS_init_msq(select_microseq, 2,
			SELECT_TARGET, 1 << target,
			SELECT_INITIATOR, 1 << initiator);

	ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret);

	if (ret)
		return (VP0_ESELECT_TIMEOUT);

	return (0);
}
Beispiel #3
0
/*
 * ppb_MS_microseq()
 *
 * Interprete a microsequence. Some microinstructions are executed at adapter
 * level to avoid function call overhead between ppbus and the adapter
 */
int
ppb_MS_microseq(device_t bus, device_t dev, struct ppb_microseq *msq, int *ret)
{
    struct ppb_data *ppb = (struct ppb_data *)device_get_softc(bus);
    struct ppb_device *ppbdev = (struct ppb_device *)device_get_ivars(dev);

    struct ppb_microseq *mi;		/* current microinstruction */
    int error;

    struct ppb_xfer *xfer;

    /* microsequence executed to initialize the transfer */
    struct ppb_microseq initxfer[] = {
        MS_PTR(MS_UNKNOWN), 	/* set ptr to buffer */
        MS_SET(MS_UNKNOWN),	/* set transfer size */
        MS_RET(0)
    };

    if (ppb->ppb_owner != dev)
        return (EACCES);

#define INCR_PC (mi ++)

    mi = msq;
    for (;;) {
        switch (mi->opcode) {
        case MS_OP_PUT:
        case MS_OP_GET:

            /* attempt to choose the best mode for the device */
            xfer = mode2xfer(bus, ppbdev, mi->opcode);

            /* figure out if we should use ieee1284 code */
            if (!xfer->loop) {
                if (mi->opcode == MS_OP_PUT) {
                    if ((error = PPBUS_WRITE(
                                     device_get_parent(bus),
                                     (char *)mi->arg[0].p,
                                     mi->arg[1].i, 0)))
                        goto error;

                    INCR_PC;
                    goto next;
                } else
                    panic("%s: IEEE1284 read not supported", __func__);
            }

            /* XXX should use ppb_MS_init_msq() */
            initxfer[0].arg[0].p = mi->arg[0].p;
            initxfer[1].arg[0].i = mi->arg[1].i;

            /* initialize transfer */
            ppb_MS_microseq(bus, dev, initxfer, &error);

            if (error)
                goto error;

            /* the xfer microsequence should not contain any
             * MS_OP_PUT or MS_OP_GET!
             */
            ppb_MS_microseq(bus, dev, xfer->loop, &error);

            if (error)
                goto error;

            INCR_PC;
            break;

        case MS_OP_RET:
            if (ret)
                *ret = mi->arg[0].i;	/* return code */
            return (0);
            break;

        default:
            /* executing microinstructions at ppc level is
             * faster. This is the default if the microinstr
             * is unknown here
             */
            if ((error = PPBUS_EXEC_MICROSEQ(
                             device_get_parent(bus), &mi)))
                goto error;
            break;
        }
next:
        continue;
    }
error:
    return (error);
}
Beispiel #4
0
Datei: mmgs1.c Projekt: XL64/mmg
/* check if edge need to be split and return a binary coding the numbers of the edges of tria iel
   that should be split according to a hausdorff distance criterion */
int chkedg(pMesh mesh,int iel) {
    pTria    pt;
    pPoint   p[3];
    double   n[3][3],t[3][3],nt[3],c1[3],c2[3],*n1,*n2,t1[3],t2[3];
    double   ps,ps2,cosn,ux,uy,uz,ll,li,dd;
    char     i,i1,i2;

    pt   = &mesh->tria[iel];
    p[0] = &mesh->point[pt->v[0]];
    p[1] = &mesh->point[pt->v[1]];
    p[2] = &mesh->point[pt->v[2]];

    /* normal recovery */
    for (i=0; i<3; i++) {
        if ( MS_SIN(p[i]->tag) ) {
            nortri(mesh,pt,n[i]);
        }
        else if ( MS_EDG(p[i]->tag) ) {
            nortri(mesh,pt,nt);
            n1  = &mesh->geom[p[i]->ig].n1[0];
            n2  = &mesh->geom[p[i]->ig].n2[0];
            ps  = n1[0]*nt[0] + n1[1]*nt[1] + n1[2]*nt[2];
            ps2 = n2[0]*nt[0] + n2[1]*nt[1] + n2[2]*nt[2];
            if ( fabs(ps) > fabs(ps2) )
                memcpy(&n[i],n1,3*sizeof(double));
            else
                memcpy(&n[i],n2,3*sizeof(double));
            memcpy(&t[i],p[i]->n,3*sizeof(double));
        }
        else
            memcpy(&n[i],p[i]->n,3*sizeof(double));
    }

    /* analyze edges */
    for (i=0; i<3; i++) {
        i1 = inxt[i];
        i2 = iprv[i];

        /* check length */
        ux = p[i2]->c[0] - p[i1]->c[0];
        uy = p[i2]->c[1] - p[i1]->c[1];
        uz = p[i2]->c[2] - p[i1]->c[2];
        ll = ux*ux + uy*uy + uz*uz;
        if ( ll > info.hmax*info.hmax ) {
            MS_SET(pt->flag,i);
            continue;
        }
        else if ( !MS_EDG(pt->tag[i]) && p[i1]->tag > MS_NOTAG && p[i2]->tag > MS_NOTAG ) {
            MS_SET(pt->flag,i);
            continue;
        }

        /* Hausdorff w/r tangent direction */
        if ( MS_EDG(pt->tag[i]) ) {
            if ( MS_SIN(p[i1]->tag) ) {
                li = 1.0 / sqrt(ll);
                t1[0] = li*ux;
                t1[1] = li*uy;
                t1[2] = li*uz;
            }
            else{
                memcpy(t1,t[i1],3*sizeof(double));
            }

            if ( MS_SIN(p[i2]->tag) ) {
                li = 1.0 / sqrt(ll);
                t2[0] = li*ux;
                t2[1] = li*uy;
                t2[2] = li*uz;
            }
            else{
                memcpy(t2,t[i2],3*sizeof(double));
            }

            ps = t1[0]*ux + t1[1]*uy + t1[2]*uz;
            ps *= ps;
            cosn = ps/ll ;
            cosn *= (1.0-cosn);
            cosn *= (0.25*ll);
            if ( cosn > info.hausd*info.hausd ) {
                MS_SET(pt->flag,i);
                continue;
            }

            ps = -(t2[0]*ux + t2[1]*uy + t2[2]*uz);
            ps *= ps;
            cosn = ps/ll ;
            cosn *= (1.0-cosn);
            cosn *= (0.25*ll);
            if ( cosn > info.hausd*info.hausd ) {
                MS_SET(pt->flag,i);
                continue;
            }
        }
        else {
            n1 = n[i1];
            n2 = n[i2];

            ps = ux*n1[0] + uy*n1[1] + uz*n1[2];
            c1[0] = (2.0*p[i1]->c[0] + p[i2]->c[0] - ps*n1[0]) / 3.0 - p[i1]->c[0];
            c1[1] = (2.0*p[i1]->c[1] + p[i2]->c[1] - ps*n1[1]) / 3.0 - p[i1]->c[1];
            c1[2] = (2.0*p[i1]->c[2] + p[i2]->c[2] - ps*n1[2]) / 3.0 - p[i1]->c[2];

            ps = -(ux*n2[0] + uy*n2[1] + uz*n2[2]);
            c2[0] = (2.0*p[i2]->c[0] + p[i1]->c[0] - ps*n2[0]) / 3.0 - p[i2]->c[0];
            c2[1] = (2.0*p[i2]->c[1] + p[i1]->c[1] - ps*n2[1]) / 3.0 - p[i2]->c[1];
            c2[2] = (2.0*p[i2]->c[2] + p[i1]->c[2] - ps*n2[2]) / 3.0 - p[i2]->c[2];

            /* squared cosines */
            ps = c1[0]*ux + c1[1]*uy + c1[2]*uz;
            ps *= ps;
            dd = c1[0]*c1[0] + c1[1]*c1[1] + c1[2]*c1[2];
            cosn  =  ps / (dd*ll);
            cosn *= (1.0-cosn);
            cosn *= (0.25*ll);
            if ( cosn > info.hausd*info.hausd ) {
                MS_SET(pt->flag,i);
                continue;
            }

            ps = -c2[0]*ux - c2[1]*uy - c2[2]*uz;
            ps *= ps;
            dd = c2[0]*c2[0]+c2[1]*c2[1]+c2[2]*c2[2];
            cosn  =  ps / (dd*ll);
            cosn *= (1.0-cosn);
            cosn *= (0.25*ll);
            if ( cosn > info.hausd*info.hausd ) {
                MS_SET(pt->flag,i);
                continue;
            }
        }
    }

    return(pt->flag);
}
Beispiel #5
0
Datei: mmgs1.c Projekt: XL64/mmg
/* analyze triangles and split if needed */
static int anaelt(pMesh mesh,pSol met,char typchk) {
    pTria    pt;
    pPoint   ppt,p1,p2;
    Hash     hash;
    Bezier   pb;
    pGeom    go;
    double   s,o[3],no[3],to[3],dd,len;
    int      vx[3],i,j,ip,ip1,ip2,ier,k,ns,nc,nt;
    char     i1,i2;
    static double uv[3][2] = { {0.5,0.5}, {0.,0.5}, {0.5,0.} };

    hashNew(&hash,mesh->np);
    ns = 0;
    s  = 0.5;
    for (k=1; k<=mesh->nt; k++) {
        pt = &mesh->tria[k];
        if ( !MS_EOK(pt) || pt->ref < 0 )  continue;
        if ( MS_SIN(pt->tag[0]) || MS_SIN(pt->tag[1]) || MS_SIN(pt->tag[2]) )  continue;

        /* check element cut */
        pt->flag = 0;
        if ( typchk == 1 ) {
            if ( !chkedg(mesh,k) )  continue;
        }
        else if ( typchk == 2 ) {
            for (i=0; i<3; i++) {
                i1 = inxt[i];
                i2 = iprv[i];
                len = lenedg(mesh,met,pt->v[i1],pt->v[i2],0);
                if ( len > LLONG )  MS_SET(pt->flag,i);
            }
            if ( !pt->flag )  continue;
        }
        ns++;

        /* geometric support */
        ier = bezierCP(mesh,k,&pb);
        assert(ier);

        /* scan edges to split */
        for (i=0; i<3; i++) {
            if ( !MS_GET(pt->flag,i) )  continue;
            i1  = inxt[i];
            i2  = iprv[i];
            ip1 = pt->v[i1];
            ip2 = pt->v[i2];
            ip = hashGet(&hash,ip1,ip2);
            if ( !MS_EDG(pt->tag[i]) && ip > 0 )  continue;

            /* new point along edge */
            ier = bezierInt(&pb,uv[i],o,no,to);
            if ( !ip ) {
                ip = newPt(mesh,o,MS_EDG(pt->tag[i]) ? to : no);
                assert(ip);
                hashEdge(&hash,ip1,ip2,ip);
                p1  = &mesh->point[ip1];
                p2  = &mesh->point[ip2];
                ppt = &mesh->point[ip];

                if ( MS_EDG(pt->tag[i]) ) {
                    ++mesh->ng;
                    assert(mesh->ng < mesh->ngmax);
                    ppt->tag = pt->tag[i];
                    if ( p1->ref == pt->edg[i] || p2->ref == pt->edg[i] )
                        ppt->ref = pt->edg[i];
                    ppt->ig  = mesh->ng;
                    go = &mesh->geom[mesh->ng];
                    memcpy(go->n1,no,3*sizeof(double));

                    dd = go->n1[0]*ppt->n[0] + go->n1[1]*ppt->n[1] + go->n1[2]*ppt->n[2];
                    ppt->n[0] -= dd*go->n1[0];
                    ppt->n[1] -= dd*go->n1[1];
                    ppt->n[2] -= dd*go->n1[2];
                    dd = ppt->n[0]*ppt->n[0] + ppt->n[1]*ppt->n[1] + ppt->n[2]*ppt->n[2];
                    if ( dd > EPSD2 ) {
                        dd = 1.0 / sqrt(dd);
                        ppt->n[0] *= dd;
                        ppt->n[1] *= dd;
                        ppt->n[2] *= dd;
                    }
                }
                if ( met->m ) {
                    if ( typchk == 1 )
                        intmet33(mesh,met,ip1,ip2,ip,s);
                    else
                        intmet(mesh,met,k,i,ip,s);
                }
            }
            else if ( pt->tag[i] & MS_GEO ) {
                ppt = &mesh->point[ip];
                go  = &mesh->geom[ppt->ig];
                memcpy(go->n2,no,3*sizeof(double));

                /* a computation of the tangent with respect to these two normals is possible */
                ppt->n[0] = go->n1[1]*go->n2[2] - go->n1[2]*go->n2[1];
                ppt->n[1] = go->n1[2]*go->n2[0] - go->n1[0]*go->n2[2];
                ppt->n[2] = go->n1[0]*go->n2[1] - go->n1[1]*go->n2[0];
                dd = ppt->n[0]*ppt->n[0] + ppt->n[1]*ppt->n[1] + ppt->n[2]*ppt->n[2];
                if ( dd > EPSD2 ) {
                    dd = 1.0 / sqrt(dd);
                    ppt->n[0] *= dd;
                    ppt->n[1] *= dd;
                    ppt->n[2] *= dd;
                }
            }
        }
    }
    if ( !ns ) {
        free(hash.item);
        return(ns);
    }

    /* step 2. checking if split by adjacent */
    for (k=1; k<=mesh->nt; k++) {
        pt = &mesh->tria[k];
        if ( !MS_EOK(pt) || pt->ref < 0 )  continue;
        else if ( pt->flag == 7 )  continue;

        /* geometric support */
        ier = bezierCP(mesh,k,&pb);
        assert(ier);
        nc = 0;

        for (i=0; i<3; i++) {
            i1 = inxt[i];
            i2 = inxt[i1];
            if ( !MS_GET(pt->flag,i) && !MS_SIN(pt->tag[i]) ) {
                ip = hashGet(&hash,pt->v[i1],pt->v[i2]);
                if ( ip > 0 ) {
                    MS_SET(pt->flag,i);
                    nc++;
                    if ( pt->tag[i] & MS_GEO ) {
                        /* new point along edge */
                        ier = bezierInt(&pb,uv[i],o,no,to);
                        assert(ier);

                        ppt = &mesh->point[ip];
                        go  = &mesh->geom[ppt->ig];
                        memcpy(go->n2,no,3*sizeof(double));

                        /* a computation of the tangent with respect to these two normals is possible */
                        ppt->n[0] = go->n1[1]*go->n2[2] - go->n1[2]*go->n2[1];
                        ppt->n[1] = go->n1[2]*go->n2[0] - go->n1[0]*go->n2[2];
                        ppt->n[2] = go->n1[0]*go->n2[1] - go->n1[1]*go->n2[0];
                        dd = ppt->n[0]*ppt->n[0] + ppt->n[1]*ppt->n[1] + ppt->n[2]*ppt->n[2];
                        if ( dd > EPSD2 ) {
                            dd = 1.0 / sqrt(dd);
                            ppt->n[0] *= dd;
                            ppt->n[1] *= dd;
                            ppt->n[2] *= dd;
                        }
                    }
                }
            }
        }
        if ( nc > 0 )  ++ns;
    }
    if ( info.ddebug && ns ) {
        fprintf(stdout,"     %d analyzed  %d proposed\n",mesh->nt,ns);
        fflush(stdout);
    }

    /* step 3. splitting */
    ns = 0;
    nt = mesh->nt;
    for (k=1; k<=nt; k++) {
        pt = &mesh->tria[k];
        if ( !MS_EOK(pt) || pt->ref < 0 )  continue;
        else if ( pt->flag == 0 )  continue;

        j  = -1;
        vx[0] = vx[1] = vx[2] = 0;
        for (i=0; i<3; i++) {
            i1 = inxt[i];
            i2 = inxt[i1];
            if ( MS_GET(pt->flag,i) ) {
                vx[i] = hashGet(&hash,pt->v[i1],pt->v[i2]);
                assert(vx[i]);
                j = i;
            }
        }
        if ( pt->flag == 1 || pt->flag == 2 || pt->flag == 4 ) {
            ier = split1(mesh,met,k,j,vx);
            assert(ier);
            ns++;
        }
        else if ( pt->flag == 7 ) {
            ier = split3(mesh,met,k,vx);
            assert(ier);
            ns++;
        }
        else {
            ier = split2(mesh,met,k,vx);
            assert(ier);
            ns++;
        }
    }
    if ( (info.ddebug || abs(info.imprim) > 5) && ns > 0 )
        fprintf(stdout,"     %7d splitted\n",ns);
    free(hash.item);

    return(ns);
}