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; }
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; }
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; }