Esempio n. 1
0
void do_auto(const char *const *argv) {
    const char *partfile;
    struct partinfo *pi, *refi, *npi, **partlist, *otherthispart;
    struct partqueue *pq;
    unsigned int i;
    int j, ap;
    long nr;
    FILE *part;
    void *buffer;
    char *p, *q;

    if (!opt_outputfile)
        badusage(_("--auto requires the use of the --output option"));
    if (!(partfile= *argv++) || *argv)
        badusage(_("--auto requires exactly one part file argument"));

    refi= nfmalloc(sizeof(struct partqueue));
    part= fopen(partfile,"r");
    if (!part) ohshite(_("unable to read part file `%.250s'"),partfile);
    if (!read_info(part,partfile,refi)) {
        if (!opt_npquiet)
            printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile);
        m_output(stdout, _("<standard output>"));
        exit(1);
    }
    fclose(part);
    scandepot();
    partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn);
    for (i = 0; i < refi->maxpartn; i++)
        partlist[i] = NULL;
    for (pq= queue; pq; pq= pq->nextinqueue) {
        pi= &pq->info;
        if (!partmatches(pi,refi)) continue;
        npi= nfmalloc(sizeof(struct partinfo));
        mustgetpartinfo(pi->filename,npi);
        addtopartlist(partlist,npi,refi);
    }
    /* If we already have a copy of this version we ignore it and prefer the
     * new one, but we still want to delete the one in the depot, so we
     * save its partinfo (with the filename) for later. This also prevents
     * us from accidentally deleting the source file. */
    otherthispart= partlist[refi->thispartn-1];
    partlist[refi->thispartn-1]= refi;
    for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--);

    if (j>=0) {

        part= fopen(partfile,"r");
        if (!part) ohshite(_("unable to reopen part file `%.250s'"),partfile);
        buffer= nfmalloc(refi->filesize);
        nr= fread(buffer,1,refi->filesize,part);
        if (nr != refi->filesize) rerreof(part,partfile);
        if (getc(part) != EOF) ohshit(_("part file `%.250s' has trailing garbage"),partfile);
        if (ferror(part)) rerr(partfile);
        fclose(part);
        p = nfmalloc(strlen(opt_depotdir) + 50);
        q = nfmalloc(strlen(opt_depotdir) + 200);
        sprintf(p, "%st.%lx", opt_depotdir, (long)getpid());
        sprintf(q, "%s%s.%lx.%x.%x", opt_depotdir, refi->md5sum,
                refi->maxpartlen,refi->thispartn,refi->maxpartn);
        part= fopen(p,"w");
        if (!part) ohshite(_("unable to open new depot file `%.250s'"),p);
        nr= fwrite(buffer,1,refi->filesize,part);
        if (nr != refi->filesize) werr(p);
        if (fflush(part))
            ohshite(_("unable to flush file '%s'"), p);
        if (fsync(fileno(part)))
            ohshite(_("unable to sync file '%s'"), p);
        if (fclose(part)) werr(p);
        if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q);

        printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package);
        /* There are still some parts missing. */
        for (i=0, ap=0; i<refi->maxpartn; i++)
            if (!partlist[i])
                printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1);
        printf(").\n");

        dir_sync_path(opt_depotdir);
    } else {

        /* We have all the parts. */
        reassemble(partlist, opt_outputfile);

        /* OK, delete all the parts (except the new one, which we never copied). */
        partlist[refi->thispartn-1]= otherthispart;
        for (i=0; i<refi->maxpartn; i++)
            if (partlist[i])
                if (unlink(partlist[i]->filename))
                    ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename);

    }

    m_output(stderr, _("<standard error>"));
}
Esempio n. 2
0
/*
 * Process machine ops.
 */
VOID
machine(struct mne *mp)
{
        char *p, *str;
        char pid[NINPUT], id[NINPUT];
        int c, d, t, t1, v1;
        a_uint op;
        struct sym *sp;
        struct expr e, e1, e2;

        clrexpr(&e);
        clrexpr(&e1);
        clrexpr(&e2);

        op = mp->m_valu;
        switch (mp->m_type) {

        case S_CPU:
                opcycles = OPCY_CPU;
                lmode = SLIST;
                switch(op) {
                default: op = DS8XCXXX;
                case DS8XCXXX: v1 = 2; str = "DS8XCXXX"; sym[2].s_addr = X_DS8XCXXX; break;
                case DS80C310: v1 = 2; str = "DS80C310"; sym[2].s_addr = X_DS80C310; break;
                case DS80C320: v1 = 2; str = "DS80C320"; sym[2].s_addr = X_DS80C320; break;
                case DS80C323: v1 = 2; str = "DS80C323"; sym[2].s_addr = X_DS80C323; break;
                case DS80C390: v1 = 3; str = "DS80C390"; sym[2].s_addr = X_DS80C390; break;
                case DS83C520: v1 = 2; str = "DS83C520"; sym[2].s_addr = X_DS83C520; break;
                case DS83C530: v1 = 2; str = "DS83C530"; sym[2].s_addr = X_DS83C530; break;
                case DS83C550: v1 = 2; str = "DS83C550"; sym[2].s_addr = X_DS83C550; break;
                case DS87C520: v1 = 2; str = "DS87C520"; sym[2].s_addr = X_DS87C520; break;
                case DS87C530: v1 = 2; str = "DS87C530"; sym[2].s_addr = X_DS87C530; break;
                case DS87C550: v1 = 2; str = "DS87C550"; sym[2].s_addr = X_DS87C550; break;
                case DS______: v1 = 2; str = "DS______"; sym[2].s_addr = X_DS______;
                        if (more()) {
                                str = p = pid;
                                d = getnb();
                                while ((c = get()) != d) {
                                        if (c == '\0') {
                                                qerr();
                                        }
                                        if (p < &pid[sizeof(pid)-3]) {
                                                *p++ = c;
                                        } else {
                                                break;
                                        }
                                }
                                *p = 0;
                        }
                        break;
                }
                if (op != 0) {
                        ds8_bytes = v1;
                        exprmasks(v1);
                }
                mchtyp = (int) op;

                sprintf(id, "__%s", str);
                sp = lookup(id);
                if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
                        err('m');
                }
                sp->s_type = S_USER;
                sp->s_addr = 1;
                sp->s_flag |= S_ASG;

                sprintf(buff, "%s %s", DS_CPU, str);
                cpu = buff;

                sp = lookup("__SFR_BITS");
                if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
                        err('m');
                }
                sp->s_type = S_USER;
                sp->s_flag |= S_ASG;

                if (more()) {
                        expr(&e, 0);
                        abscheck(&e);
                        sp->s_addr = e.e_addr;
                } else {
                        sp->s_addr = 1;
                }
                break;

        case S_AMODE:
                opcycles = OPCY_AMODE;
                if ((mchtyp != 0) && (mchtyp != DS80C390)) {
                        err('o');
                        break;
                }
                expr(&e, 0);
                abscheck(&e);
                amode = (int) e.e_addr;
                if ((amode < 0) || (amode > 2)) {
                        amode = 0;
                        err('o');
                }
                if ((c = getnb()) == ',') {
                        expr(&e1, 0);
                        abscheck(&e1);
                        if (e1.e_addr != 0) {
/* mov  ta,#0aah */             outab(0x075);   outab(0x0C7);   outab(0x0AA);
/* mov  ta,#055h */             outab(0x075);   outab(0x0C7);   outab(0x055);
/* mov  acon,#amode */          outab(0x075);   outab(0x09D);   outab(amode);
                        } else {
                                lmode = SLIST;
                        }
                } else {
                        unget(c);
                        lmode = SLIST;
                }
                break;

        case S_BITS:
                if (ds8_bytes == 0) {
                        ds8_bytes = (int) op;
                        exprmasks(ds8_bytes);
                } else
                if (ds8_bytes != (int) op) {
                        err('m');
                }
                opcycles = OPCY_BITS;
                lmode = SLIST;
                break;

        case S_INH:
                outab(op);
                break;

        case S_JMP11:
                expr(&e, 0);
                if (amode == 2) {
                        outr3bm(&e, R_J19, op);
                } else {
                        outrwm(&e, R_J11, op);
                }
                break;

        case S_JMP16:
                expr(&e, 0);
                outab(op);
                if (amode == 2) {
                        outr3b(&e, R_NORM);
                } else {
                        outrw(&e, R_NORM);
                }
                break;

        case S_ACC:
                t = addr(&e);
                if (t != S_A)
                        aerr();
                outab(op);
                break;

        case S_TYP1:
                /* A, direct, @R0, @R1, R0 to R7.  "INC" also allows DPTR */
                t = addr(&e);

                switch (t) {
                case S_A:
                        outab(op + 4);
                        break;

                case S_DIR:
                case S_EXT:
                        /* Direct is also legal */
                        outab(op + 5);
                        outrb(&e, R_PAG0);
                        break;

                case S_AT_R:
                        outab(op + 6 + e.e_addr);
                        break;

                case S_REG:
                        outab(op + 8 + e.e_addr);
                        break;

                case S_DPTR:
                        if (op != 0)
                                /* only INC (op=0) has DPTR mode */
                                aerr();
                        else
                                outab( 0xA3);
                        break;

                default:
                        aerr();
                }
                break;

        case S_TYP2:
                /* A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);

                switch (t1) {
                case S_IMMED:
                        outab(op + 4);
                        outrb(&e1, R_NORM);
                        break;

                case S_DIR:
                case S_EXT:
                        outab(op + 5);
                        outrb(&e1, R_PAG0);
                        break;

                case S_AT_R:
                        outab(op + 6 + e1.e_addr);
                        break;

                case S_REG:
                        outab(op + 8 + (e1.e_addr));
                        break;

                default:
                        aerr();
                }
                break;

        case S_TYP3:
                /* dir,A; dir,#imm;
                 * A,#imm; A,direct; A,@R0; A,@R1; A,R0 to A,R7
                 * C,direct;  C,/direct
                 */
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                switch (t) {
                case S_DIR:
                case S_EXT:
                        switch (t1) {
                        case S_A:
                                outab(op + 2);
                                outrb(&e, R_PAG0);
                                break;

                        case S_IMMED:
                                outab(op + 3);
                                outrb(&e, R_PAG0);
                                outrb(&e1, R_NORM);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_A:
                        switch (t1) {
                        case S_IMMED:
                                outab(op + 4);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(op + 5);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_AT_R:
                                outab(op + 6 + e1.e_addr);
                                break;

                        case S_REG:
                                outab(op + 8 + e1.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_C:
                        /* XRL has no boolean version.  Trap it */
                        if (op == 0x60)
                                aerr();

                        switch (t1) {
                        case S_DIR:
                        case S_EXT:
                                outab(op + 0x32);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_NOT_BIT:
                                outab(op + 0x60);
                                outrb(&e1, R_PAG0);
                                break;

                        default:
                                aerr();
                        }
                        break;

                default:
                        aerr();
                }
                break;

        case S_TYP4:
                /* A,direct; A,@R0; A,@R1; A,R0 to A,R7 */
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);

                switch (t1) {
                case S_DIR:
                case S_EXT:
                        outab(op + 5);
                        outrb(&e1, R_PAG0);
                        break;

                case S_AT_R:
                        outab(op + 6 + e1.e_addr);
                        break;

                case S_REG:
                        outab(op + 8 + e1.e_addr);
                        break;

                default:
                        aerr();
                }
                break;

        /* MOV instruction, all modes */
        case S_MOV:
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                switch (t) {
                case S_A:
                        switch (t1) {
                        case S_IMMED:
                                outab(0x74);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0xE5);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_AT_R:
                                outab(0xE6 + e1.e_addr);
                                break;

                        case S_REG:
                                outab(0xE8 + e1.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_REG:
                        switch (t1) {
                        case S_A:
                                outab(0xF8 + e.e_addr);
                                break;

                        case S_IMMED:
                                outab(0x78 + e.e_addr);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0xA8 + e.e_addr);
                                outrb(&e1, R_PAG0);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_DIR:
                case S_EXT:
                        switch (t1) {
                        case S_A:
                                outab(0xF5);
                                outrb(&e, R_PAG0);
                                break;

                        case S_IMMED:
                                outab(0x75);
                                outrb(&e, R_PAG0);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0x85);
                                outrb(&e1, R_PAG0);
                                outrb(&e, R_PAG0);
                                break;

                        case S_AT_R:
                                outab(0x86 + e1.e_addr);
                                outrb(&e, R_PAG0);
                                break;

                        case S_REG:
                                outab(0x88 + e1.e_addr);
                                outrb(&e, R_PAG0);
                                break;

                        case S_C:
                                outab(0x92);
                                outrb(&e, R_PAG0);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_AT_R:
                        switch (t1) {
                        case S_IMMED:
                                outab(0x76 + e.e_addr);
                                outrb(&e1, R_NORM);
                                break;

                        case S_DIR:
                        case S_EXT:
                                outab(0xA6 + e.e_addr);
                                outrb(&e1, R_PAG0);
                                break;

                        case S_A:
                                outab(0xF6 + e.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_C:
                        if ((t1 != S_DIR) && (t1 != S_EXT))
                                aerr();
                        outab(0xA2);
                        outrb(&e1, R_PAG0);
                        break;

                case S_DPTR:
                        if (t1 != S_IMMED)
                                aerr();
                        outab(0x90);
                        if (amode == 2)
                                outr3b(&e1, R_NORM);
                        else
                                outrw(&e1, R_NORM);
                        break;

                default:
                        aerr();
                }
                break;

        case S_BITBR:   /* JB, JBC, JNB bit,rel */
                /* Branch on bit set/clear */
                t = addr(&e);
                if ((t != S_DIR) && (t != S_EXT))
                        aerr();
                /* sdcc svn rev #4994: fixed bug 1865114 */
                comma(1);
                expr(&e1, 0);

                outab(op);
                outrb(&e, R_PAG0);

                if (mchpcr(&e1)) {
                        v1 = (int) (e1.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e1, R_PCR);
                }
                if (e1.e_mode != S_USER)
                        rerr();
                break;

        case S_BR:  /* JC, JNC, JZ, JNZ */
                /* Relative branch */
                /* sdcc svn rev #4994: fixed bug 1865114 */
                expr(&e1, 0);
                outab(op);

                if (mchpcr(&e1)) {
                        v1 = (int) (e1.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e1, R_PCR);
                }
                if (e1.e_mode != S_USER)
                        rerr();
                break;

        case S_CJNE:
                /* A,#;  A,dir;  @R0,#;  @R1,#;  Rn,# */
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                /* Benny */
                comma(1);
                expr(&e2, 0);

                switch (t) {
                case S_A:
                        if (t1 == S_IMMED) {
                                outab(op + 4);
                                outrb(&e1, R_NORM);
                        }
                        else if ((t1 == S_DIR) || (t1 == S_EXT)) {
                                outab(op + 5);
                                outrb(&e1, R_PAG0);
                        }
                        else
                                aerr();
                        break;

                case S_AT_R:
                        outab(op + 6 + e.e_addr);
                        if (t1 != S_IMMED)
                                aerr();
                        outrb(&e1, R_NORM);
                        break;

                case S_REG:
                        outab(op + 8 + e.e_addr);
                        if (t1 != S_IMMED)
                                aerr();
                        outrb(&e1, R_NORM);
                        break;

                default:
                        aerr();
                        break;
                }

                /* branch destination */
                if (mchpcr(&e2)) {
                        v1 = (int) (e2.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e2, R_PCR);
                }
                if (e2.e_mode != S_USER)
                        rerr();
                break;

        case S_DJNZ:
                /* Dir,dest;  Reg,dest */
                t = addr(&e);
                /* sdcc svn rev #4994: fixed bug 1865114 */
                comma(1);
                expr(&e1, 0);

                switch (t) {
                case S_DIR:
                case S_EXT:
                        outab(op + 5);
                        outrb(&e, R_PAG0);
                        break;

                case S_REG:
                        outab(op + 8 + e.e_addr);
                        break;

                default:
                        aerr();
                }

                /* branch destination */
                /* sdcc svn rev #4994: fixed bug 1865114 */
                if (mchpcr(&e1)) {
                        v1 = (int) (e1.e_addr - dot.s_addr - 1);
                        /* sdcc svn rev #602: Fix some path problems */
                        if (pass == 2 && ((v1 < -128) || (v1 > 127)))
                                aerr();
                        outab(v1);
                } else {
                        outrb(&e1, R_PCR);
                }
                if (e1.e_mode != S_USER)
                        rerr();
                break;

        case S_JMP:
                /* @A+DPTR */
                t = addr(&e);
                if (t != S_AT_ADP)
                        aerr();
                outab(op);
                break;

        case S_MOVC:
                /* A,@A+DPTR  A,@A+PC */
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);
                if (t1 == S_AT_ADP)
                        outab(0x93);
                else if (t1 == S_AT_APC)
                        outab(0x83);
                else
                        aerr();
                break;

        case S_MOVX:
                /* A,@DPTR  A,@R0  A,@R1  @DPTR,A  @R0,A  @R1,A */
                t = addr(&e);
                comma(1);
                t1 = addr(&e1);

                switch (t) {
                case S_A:
                        switch (t1) {
                        case S_AT_DP:
                                outab(0xE0);
                                break;

                        case S_AT_R:
                                outab(0xE2 + e1.e_addr);
                                break;

                        default:
                                aerr();
                        }
                        break;

                case S_AT_DP:
                        if (t1 == S_A)
                                outab(0xF0);
                        else
                                aerr();
                        break;

                case S_AT_R:
                        if (t1 == S_A)
                                outab(0xF2 + e.e_addr);
                        else
                                aerr();
                        break;

                default:
                        aerr();
                }
                break;

        /* MUL/DIV A,B */
        case S_AB:
                t = addr(&e);
                if (t != S_RAB)
                        aerr();
                outab(op);
                break;

        /* CLR or CPL:  A, C, or bit */
        case S_ACBIT:
                t = addr(&e);
                switch (t) {
                case S_A:
                        if (op == 0xB2)
                                outab(0xF4);
                        else
                                outab(0xE4);
                        break;

                case S_C:
                        outab(op+1);
                        break;

                case S_DIR:
                case S_EXT:
                        outab(op);
                        outrb(&e, R_PAG0);
                        break;

                default:
                        aerr();
                }
                break;

        /* SETB C or bit */
        case S_SETB:
                t = addr(&e);
                switch (t) {
                case S_C:
                        outab(op+1);
                        break;

                case S_DIR:
                case S_EXT:
                        outab(op);
                        outrb(&e, R_PAG0);
                        break;

                default:
                        aerr();
                }
                break;

        /* direct */
        case S_DIRECT:
                t = addr(&e);
                if (t == S_A) {
                        e.e_addr = 0xE0;
                        e.e_mode = S_DIR;
                } else
                if ((t != S_DIR) && (t != S_EXT)) {
                        aerr();
                        break;
                }
                outab(op);
                outrb(&e, R_PAG0);
                break;

        /* XCHD A,@Rn */
        case S_XCHD:
                t = addr(&e);
                if (t != S_A)
                        aerr();
                comma(1);
                t1 = addr(&e1);
                switch (t1) {
                case S_AT_R:
                        outab(op + e1.e_addr);
                        break;

                default:
                        aerr();
                }
                break;

        default:
                opcycles = OPCY_ERR;
                err('o');
                break;
        }
        if (opcycles == OPCY_NONE) {
                opcycles = ds8pg1[cb[0] & 0xFF];
        }
}