Exemplo n.º 1
0
static
int
do_load(char *file_name, struct membuf *mem)
{
    struct load_info info[1];
    unsigned char *p;

    membuf_clear(mem);
    membuf_append(mem, NULL, 65536);
    p = membuf_get(mem);

    info->basic_txt_start = -1;

    load_located(file_name, p, info);

    /* move memory to beginning of buffer */
    membuf_truncate(mem, info->end);
    membuf_trim(mem, info->start);

    LOG(LOG_NORMAL, (" Crunching from $%04X to $%04X.",
                     info->start, info->end));
    return info->start;
}
Exemplo n.º 2
0
static
int
do_loads(int filec, char *filev[], struct membuf *mem,
         int basic_txt_start, int sys_token,
         int *basic_var_startp, int *runp, int trim_sys)
{
    int run = -1;
    int min_start = 65537;
    int max_end = -1;
    int basic_code = 0;
    int i;
    unsigned char *p;
    struct load_info info[1];


    membuf_clear(mem);
    membuf_append(mem, NULL, 65536);
    p = membuf_get(mem);

    for (i = 0; i < filec; ++i)
    {
        info->basic_txt_start = basic_txt_start;
        load_located(filev[i], p, info);
        run = info->run;
        if(run != -1 && runp != NULL)
        {
            LOG(LOG_DEBUG, ("Propagating found run address $%04X.\n",
                            info->run));
            *runp = info->run;
        }

        /* do we expect any basic file? */
        if(basic_txt_start >= 0)
        {
            if(info->basic_var_start >= 0)
            {
                basic_code = 1;
                if(basic_var_startp != NULL)
                {
                    *basic_var_startp = info->basic_var_start;
                }
                if(runp != NULL && run == -1)
                {
                    /* only if we didn't get run address from load_located
                     * (run is not -1 if we did) */
                    int stub_len;
                    run = find_sys(p + basic_txt_start, sys_token, &stub_len);
                    *runp = run;
                    if (trim_sys &&
                        basic_txt_start == info->start &&
                        min_start >= info->start)
                    {
                        if (run >= info->start &&
                            run < info->start + stub_len)
                        {
                            /* the run address points into the sys stub,
                               trim up to it but no further */
                            info->start = run;
                        }
                        else
                        {
                            /* trim the sys stub*/
                            info->start += stub_len;
                        }
                    }
                }
            }
        }

        if (info->start < min_start)
        {
            min_start = info->start;
        }
        if (info->end > max_end)
        {
            max_end = info->end;
        }
    }

    if(basic_txt_start >= 0 && !basic_code && run == -1)
    {
        /* no program loaded to the basic start */
        LOG(LOG_ERROR, ("\nError: nothing loaded at the start of basic "
                        "text address ($%04X).\n",
                        basic_txt_start));
        exit(1);
    }

    /* if we have a basic code loaded and we are doing a proper basic start
     * (the caller don't expect a sys address so runp is NULL */
    if(basic_code && runp == NULL)
    {
        int valuepos = basic_txt_start - 1;
        /* the byte immediatley preceeding the basic start must be 0
         * for basic to function properly. */
        if(min_start > valuepos)
        {
            /* It not covered by the files to crunch. Since the
             * default fill value is 0 we don't need to set it but we
             * need to include that location in the crunch as well. */
            min_start = valuepos;
        }
        else
        {
            int value = p[valuepos];
            /* it has been covered by at least one file. Let's check
             * if it is zero. */
            if(value != 0)
            {
                /* Hm, its not, danger Will Robinson! */
                LOG(LOG_WARNING,
                    ("Warning, basic will probably not work since the value of"
                     " the location \npreceeding the basic start ($%04X)"
                     " is not 0 but %d.\n", valuepos, value));
            }
        }
    }

    /* move memory to beginning of buffer */
    membuf_truncate(mem, max_end);
    membuf_trim(mem, min_start);

    return min_start;
}
Exemplo n.º 3
0
int assemble(struct membuf *source, struct membuf *dest)
{
    struct vec guesses_history[1];
    struct map guesses_storage[1];
    int dest_pos;
    int result;

    dump_sym_table(LOG_DEBUG, s->initial_symbols);

    vec_init(guesses_history, sizeof(struct map));
    s->guesses = NULL;
    dest_pos = membuf_memlen(dest);
    for(;;)
    {

        map_put_all(s->sym_table, s->initial_symbols);
        named_buffer_copy(s->named_buffer, s->initial_named_buffer);
        map_init(guesses_storage);

        if(s->guesses != NULL)
        {
            /* copy updated guesses from latest pass */
            map_put_all(guesses_storage, s->guesses);
        }
        s->guesses = guesses_storage;

        result = assembleSinglePass(source, dest);
        if(result != 0)
        {
            /* the assemble pass failed */
            break;
        }

        /* check if any guessed symbols was wrong and update them
         * to their actual value */
        if(wasFinalPass())
        {
            /* The assemble pass succeeded without any wrong guesses,
             * we're done */
            break;
        }
        if(loopDetect(guesses_history))
        {
            /* More passes would only get us into a loop */
            LOG(LOG_VERBOSE, ("Aborting due to loop.\n"));
            result = -1;
            break;
        }

        LOG(LOG_VERBOSE, ("Trying another pass.\n"));

        /* allocate storage for the guesses in the history vector */
        s->guesses = vec_push(guesses_history, s->guesses);

        parse_reset();
        membuf_truncate(dest, dest_pos);
    }
    map_free(guesses_storage);
    vec_free(guesses_history, (cb_free*)map_free);
    s->guesses = NULL;
    return result;
}