コード例 #1
0
ファイル: parse.c プロジェクト: shattered/macro11
int get_mode(
    char *cp,
    char **endp,
    ADDR_MODE *mode)
{
    EX_TREE        *value;

    mode->offset = NULL;
    mode->rel = 0;
    mode->type = 0;

    cp = skipwhite(cp);

    /* @ means "indirect," sets bit 3 */
    if (*cp == '@') {
        cp++;
        mode->type |= 010;
    }

    /* Immediate modes #imm and @#imm */
    if (*cp == '#') {
        cp++;
        mode->type |= 027;
        mode->offset = parse_expr(cp, 0);
        if (endp)
            *endp = mode->offset->cp;
        return TRUE;
    }

    /* Check for -(Rn) */

    if (*cp == '-') {
        char           *tcp = skipwhite(cp + 1);

        if (*tcp++ == '(') {
            unsigned        reg;

            /* It's -(Rn) */
            value = parse_expr(tcp, 0);
            reg = get_register(value);
            if (reg == NO_REG || (tcp = skipwhite(value->cp), *tcp++ != ')')) {
                free_tree(value);
                return FALSE;
            }
            mode->type |= 040 | reg;
            if (endp)
                *endp = tcp;
            free_tree(value);
            return TRUE;
        }
    }

    /* Check for (Rn) */
    if (*cp == '(') {
        char           *tcp;
        unsigned        reg;

        value = parse_expr(cp + 1, 0);
        reg = get_register(value);

        if (reg == NO_REG || (tcp = skipwhite(value->cp), *tcp++ != ')')) {
            free_tree(value);
            return FALSE;
        }

        tcp = skipwhite(tcp);
        if (*tcp == '+') {
            tcp++;                     /* It's (Rn)+ */
            if (endp)
                *endp = tcp;
            mode->type |= 020 | reg;
            free_tree(value);
            return TRUE;
        }

        if (mode->type == 010) {       /* For @(Rn) there's an implied 0 offset */
            mode->offset = new_ex_lit(0);
            mode->type |= 060 | reg;
            free_tree(value);
            if (endp)
                *endp = tcp;
            return TRUE;
        }

        mode->type |= 010 | reg;       /* Mode 10 is register indirect as
                                          in (Rn) */
        free_tree(value);
        if (endp)
            *endp = tcp;
        return TRUE;
    }

    /* Modes with an offset */

    mode->offset = parse_expr(cp, 0);

    cp = skipwhite(mode->offset->cp);

    if (*cp == '(') {
        unsigned        reg;

        /* indirect register plus offset */
        value = parse_expr(cp + 1, 0);
        reg = get_register(value);
        if (reg == NO_REG || (cp = skipwhite(value->cp), *cp++ != ')')) {
            free_tree(value);
            return FALSE;              /* Syntax error in addressing mode */
        }

        mode->type |= 060 | reg;

        free_tree(value);

        if (endp)
            *endp = cp;
        return TRUE;
    }

    /* Plain old expression. */

    if (endp)
        *endp = cp;

    /* It might be a register, though. */
    if (mode->offset->type == EX_SYM) {
        SYMBOL         *sym = mode->offset->data.symbol;

        if (sym->section->type == SECTION_REGISTER) {
            free_tree(mode->offset);
            mode->offset = NULL;
            mode->type |= sym->value;
            return TRUE;
        }
    }

    /* It's either 067 (PC-relative) or 037 (absolute) mode, depending */
    /* on user option. */

    if (mode->type & 010) {            /* Have already noted indirection? */
        mode->type |= 067;             /* If so, then PC-relative is the only
                                          option */
        mode->rel = 1;                 /* Note PC-relative */
    } else if (enabl_ama) {            /* User asked for absolute adressing? */
        mode->type |= 037;             /* Give it to him. */
    } else {
        mode->type |= 067;             /* PC-relative */
        mode->rel = 1;                 /* Note PC-relative */
    }

    return TRUE;
}
コード例 #2
0
ファイル: macro11.c プロジェクト: Rhialto/simtools
int main(
    int argc,
    char *argv[])
{
    char           *fnames[32];
    int             nr_files = 0;
    FILE           *obj = NULL;
    TEXT_RLD        tr;
    char           *objname = NULL;
    char           *lstname = NULL;
    int             arg;
    int             i;
    STACK           stack;
    int             errcount;

    if (argc <= 1) {
        print_help();
        exit(EXIT_FAILURE);
    }

    for (arg = 1; arg < argc; arg++)
        if (*argv[arg] == '-') {
            char           *cp;

            cp = argv[arg] + 1;
            if (!stricmp(cp, "h")) {
                print_help();
            } else if (!stricmp(cp, "v")) {
                print_version(stderr);
            } else if (!stricmp(cp, "e")) {
                /* Followed by options to enable */
                /* Since /SHOW and /ENABL option names don't overlap,
                   I consolidate. */
                if(arg >= argc-1 || !isalpha((unsigned char)*argv[arg+1])) {
                    usage("-e must be followed by an option to enable\n");
                }
                upcase(argv[++arg]);
                enable_tf(argv[arg], 1);
            } else if (!stricmp(cp, "d")) {
                /* Followed by an option to disable */
                if(arg >= argc-1 || !isalpha((unsigned char)*argv[arg+1])) {
                    usage("-d must be followed by an option to disable\n");
                }
                upcase(argv[++arg]);
                enable_tf(argv[arg], 0);
            } else if (!stricmp(cp, "m")) {
                /* Macro library */
                /* This option gives the name of an RT-11 compatible
                   macro library from which .MCALLed macros can be
                   found. */
                if(arg >= argc-1 || *argv[arg+1] == '-') {
                    usage("-m must be followed by a macro library file name\n");
                }
                arg++;
                int allow_olb = strcmp(argv[argc-1], "-x") == 0;
                mlbs[nr_mlbs] = mlb_open(argv[arg], allow_olb);
                if (mlbs[nr_mlbs] == NULL) {
                    fprintf(stderr, "Unable to register macro library %s\n", argv[arg]);
                    exit(EXIT_FAILURE);
                }
                nr_mlbs++;
            } else if (!stricmp(cp, "p")) {
                /* P for search path */
                /* The -p option gives the name of a directory in
                   which .MCALLed macros may be found.  */  {

                    if(arg >= argc-1 || *argv[arg+1] == '-') {
                        usage("-p must be followed by a macro search directory\n");
                    }

                    append_env("MCALL", argv[arg+1]);
                    arg++;
                }
            } else if (!stricmp(cp, "I")) {
                /* I for include path */
                /* The -I option gives the name of a directory in
                   which .included files may be found.  */  {

                    if(arg >= argc-1 || *argv[arg+1] == '-') {
                        usage("-I must be followed by a include file search directory\n");
                    }
                    append_env("INCLUDE", argv[arg+1]);

                    arg++;
                }
            } else if (!stricmp(cp, "o")) {
                /* The -o option gives the object file name (.OBJ) */
                if(arg >= argc-1 || *argv[arg+1] == '-') {
                    usage("-o must be followed by the object file name\n");
                }
                ++arg;
                objname = argv[arg];
            } else if (!stricmp(cp, "l")) {
                /* The option -l gives the listing file name (.LST) */
                /* -l - enables listing to stdout. */
                if(arg >= argc-1 ||
                        (argv[arg+1][0] == '-' && argv[arg+1][1] != '\0')) {
                    usage("-l must be followed by the listing file name (- for standard output)\n");
                }
                lstname = argv[++arg];
                if (strcmp(lstname, "-") == 0)
                    lstfile = stdout;
                else
                    lstfile = fopen(lstname, "w");
            } else if (!stricmp(cp, "x")) {
                /* The -x option invokes macro11 to expand the
                   contents of the registered macro libraries (see -m)
                   into individual .MAC files in the current
                   directory.  No assembly of input is done.  This
                   must be the last command line option.  */
                int             m;

                if(arg != argc-1) {
                    usage("-x must be the last option\n");
                }
                for (m = 0; m < nr_mlbs; m++)
                    mlb_extract(mlbs[m]);
                return EXIT_SUCCESS;
            } else if (!stricmp(cp, "ysl")) {
                /* set symbol_len */
                if (arg >= argc-1) {
                    usage("-s must be followed by a number\n");
                } else {
                    char           *s = argv[++arg];
                    char           *endp;
                    int             sl = strtol(s, &endp, 10);

                    if (*endp || sl < SYMMAX_DEFAULT || sl > SYMMAX_MAX) {
                        usage("-s must be followed by a number\n");
                    }
                    symbol_len = sl;
                }
            } else if (!stricmp(cp, "yus")) {
                /* allow underscores */
                symbol_allow_underscores = 1;
            } else if (!stricmp(cp, "yl1")) {
                /* list the first pass, in addition to the second */
                list_pass_0++;
            } else if (!stricmp(cp, "yd")) {
                enabl_debug++;
            } else {
                fprintf(stderr, "Unknown option %s\n", argv[arg]);
                print_help();
                exit(EXIT_FAILURE);
            }
        } else {
            fnames[nr_files++] = argv[arg];
        }

    if (objname) {
        obj = fopen(objname, "wb");
        if (obj == NULL)
            return EXIT_FAILURE;
    }

    add_symbols(&blank_section);

    text_init(&tr, NULL, 0);

    module_name = memcheck(strdup(".MAIN."));

    xfer_address = new_ex_lit(1);      /* The undefined transfer address */

    stack_init(&stack);
    /* Push the files onto the input stream in reverse order */
    for (i = nr_files - 1; i >= 0; --i) {
        STREAM         *str = new_file_stream(fnames[i]);

        if (str == NULL) {
            report(NULL, "Unable to open file %s\n", fnames[i]);
            exit(EXIT_FAILURE);
        }
        stack_push(&stack, str);
    }

    DOT = 0;
    current_pc->section = &blank_section;
    last_dot_section = NULL;
    pass = 0;
    stmtno = 0;
    lsb = 0;
    next_lsb = 1;
    lsb_used = 0;
    last_macro_lsb = -1;
    last_locsym = 32767;
    last_cond = -1;
    sect_sp = -1;
    suppressed = 0;

    assemble_stack(&stack, &tr);

    if (list_pass_0 && lstfile) {
        list_symbol_table();
    }
#if 0
    if (enabl_debug > 1)
        dump_all_macros();
#endif

    assert(stack.top == NULL);

    migrate_implicit();                /* Migrate the implicit globals */
    write_globals(obj);                /* Write the global symbol dictionary */

#if 0
    sym_hist(&symbol_st, "symbol_st"); /* Draw a symbol table histogram */
#endif


    text_init(&tr, obj, 0);

    stack_init(&stack);                /* Superfluous... */
    /* Re-push the files onto the input stream in reverse order */
    for (i = nr_files - 1; i >= 0; --i) {
        STREAM         *str = new_file_stream(fnames[i]);

        if (str == NULL) {
            report(NULL, "Unable to open file %s\n", fnames[i]);
            exit(EXIT_FAILURE);
        }
        stack_push(&stack, str);
    }

    DOT = 0;

    current_pc->section = &blank_section;
    last_dot_section = NULL;

    pass = 1;
    stmtno = 0;
    lsb = 0;
    next_lsb = 1;
    lsb_used = 0;
    last_macro_lsb = -1;
    last_locsym = 32767;
    pop_cond(-1);
    sect_sp = -1;
    suppressed = 0;

    errcount = assemble_stack(&stack, &tr);

    text_flush(&tr);

    while (last_cond >= 0) {
        report(NULL, "%s:%d: Unterminated conditional\n", conds[last_cond].file, conds[last_cond].line);
        pop_cond(last_cond - 1);
        errcount++;
    }

    for (i = 0; i < nr_mlbs; i++)
        mlb_close(mlbs[i]);

    write_endmod(obj);

    if (obj != NULL)
        fclose(obj);

    if (errcount > 0)
        fprintf(stderr, "%d Errors\n", errcount);

    if (lstfile) {
        list_symbol_table();
    }

    if (lstfile && strcmp(lstname, "-") != 0)
        fclose(lstfile);

    return errcount > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}