URL
https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk
Subversion Repositories open8_urisc
[/] [open8_urisc/] [trunk/] [Open8 Tools/] [open8_src/] [open8_as/] [pass_4.c] - Rev 179
Go to most recent revision | Compare with Previous | Blame | View Log
#include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "defines.h" #include "include_file.h" #include "listfile.h" #include "pass_4.h" #include "parse.h" #include "stack.h" extern struct section_def *sections_first, *sections_last, *sec_tmp, *sec_next; extern struct incbin_file_data *incbin_file_data_first, *ifd_tmp; extern struct export_def *export_first, *export_last; extern struct stack *stacks_first, *stacks_tmp, *stacks_last, *stacks_header_first, *stacks_header_last; extern struct label_def *label_tmp, *label_last, *labels; extern struct definition *defines, *tmp_def, *next_def; extern struct file_name_info *file_name_info_first; extern struct slot slots[256]; extern FILE *file_out_ptr; extern unsigned char *rom_banks, *rom_banks_usage_table; extern char gba_tmp_name[32], tmp[4096], name[32], *final_name; extern int rombanks, ind, inz, output_format, test_mode, listfile_data; extern int romtype, rambanks, emptyfill, max_address; extern int rambanks_defined, verbose_mode; extern int section_status; extern int banksize, banksize_defined; extern int slots_amount; extern int *banks, *bankaddress, rombankmap_defined; extern int latest_stack, stacks_outside, stacks_inside; extern int bankheader_status; extern int smc_defined, makefile_rules; struct label_def *unknown_labels = NULL, *unknown_labels_last = NULL, *tul, *ltmp; struct label_def *unknown_header_labels = NULL, *unknown_header_labels_last = NULL; unsigned int pc_bank = 0, pc_full = 0, rom_bank, mem_insert_overwrite, slot, pc_slot, pc_slot_max; int filename_id, line_number; #define WRITEOUT_OV fprintf(final_ptr, "%c%c%c%c", (ov>>24)&0xFF, (ov>>16)&0xFF, (ov>>8)&0xFF, ov&0xFF); #define WRITEOUT_DOU { \ cp = (unsigned char *)&dou; \ fprintf(final_ptr, "%c%c%c%c%c%c%c%c", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); \ } int new_unknown_reference(int type) { struct label_def *t; t = malloc(sizeof(struct label_def)); if (t == NULL) { fprintf(stderr, "%s:%d: NEW_UNKNOWN_REFERENCE: Out of memory.\n", get_file_name(filename_id), line_number); return FAILED; } t->symbol = NO; strcpy(t->label, tmp); t->next = NULL; t->type = type; t->filename_id = filename_id; t->linenumber = line_number; t->section_status = section_status; if (section_status == ON) { t->section_id = sec_tmp->id; t->address = sec_tmp->i; /* relative address, to the beginning of the section */ } else { t->section_id = 0; t->address = pc_bank; /* bank address, in ROM memory */ } t->bank = rom_bank; t->slot = slot; /* outside bank header section */ if (bankheader_status == OFF) { if (unknown_labels_last == NULL) { unknown_labels = t; unknown_labels_last = t; } else { unknown_labels_last->next = t; unknown_labels_last = t; } } /* bank header section */ else { if (t->label[0] == '_') { fprintf(stderr, "%s:%d: NEW_UNKNOWN_REFERENCE: Referring to a local label (\"%s\") from inside a bank header section is not allowed.\n", get_file_name(filename_id), line_number, t->label); return FAILED; } if (unknown_header_labels_last == NULL) { unknown_header_labels = t; unknown_header_labels_last = t; } else { unknown_header_labels_last->next = t; unknown_header_labels_last = t; } } return SUCCEEDED; } int pass_4(void) { unsigned char *cp; FILE *final_ptr; double dou; char *t, c; int i, o, z, y, add_old = 0; int x, q, ov; float f; section_status = OFF; bankheader_status = OFF; mem_insert_overwrite = OFF; if (verbose_mode == ON) printf("Internal pass 2...\n"); if ((file_out_ptr = fopen(gba_tmp_name, "rb")) == NULL) { fprintf(stderr, "INTERNAL_PASS_2: Error opening file \"%s\".\n", gba_tmp_name); return FAILED; } while (fread(&c, 1, 1, file_out_ptr) != 0) { switch (c) { case 'E': continue; case 'g': fscanf(file_out_ptr, "%*s "); continue; case 'G': continue; case 'f': fscanf(file_out_ptr, "%d ", &filename_id); continue; case 'k': fscanf(file_out_ptr, "%d ", &line_number); continue; /* SECTION */ case 'A': case 'S': if (c == 'A') fscanf(file_out_ptr, "%d %d ", &x, &ind); else fscanf(file_out_ptr, "%d ", &x); add_old = pc_bank; sec_tmp = sections_first; while (sec_tmp != NULL) { if (sec_tmp->id == x) break; sec_tmp = sec_tmp->next; } /* skip all dead sections */ if (sec_tmp->alive == OFF) continue; if (c == 'A') sec_tmp->address = ind; ind = 0; if (sec_tmp->maxsize_status == ON) { if (sec_tmp->maxsize < sec_tmp->size) { fprintf(stderr, "%s: INTERNAL_PASS_2: Section \"%s\" doesn't fit into the specified %d bytes. Enlarging to %d bytes.\n", get_file_name(filename_id), sec_tmp->name, sec_tmp->maxsize, sec_tmp->size); } else if (sec_tmp->size < sec_tmp->maxsize) { sec_tmp->size = sec_tmp->maxsize; ind = 1; } } sec_tmp->data = malloc(sizeof(unsigned char) * sec_tmp->size); if (sec_tmp->data == NULL) { fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Out of memory when trying to allocate room for section \"%s\".\n", get_file_name(filename_id), line_number, sec_tmp->name); return FAILED; } /* fill the padded area with _emptyfill_ */ if (ind == 1) memset(sec_tmp->data, emptyfill, sec_tmp->size); if (strcmp(sec_tmp->name, "BANKHEADER") == 0) bankheader_status = ON; sec_tmp->i = 0; section_status = ON; continue; /* ENDS */ case 's': section_status = OFF; bankheader_status = OFF; /* some sections don't affect the ORG outside of them */ if (sec_tmp->advance_org == NO) { pc_bank = add_old; pc_full = bankaddress[rom_bank] + pc_bank; pc_slot = slots[slot].address + pc_bank; pc_slot_max = slots[slot].address + slots[slot].size; } continue; /* DSB & DSW */ case 'x': fscanf(file_out_ptr, "%d %d", &ind, &x); while (ind > 0) { if (mem_insert(x) == FAILED) return FAILED; ind--; } continue; case 'X': fscanf(file_out_ptr, "%d %d", &ind, &inz); i = inz & 0xFF; inz = (inz >> 8) & 0xFF; while (ind > 0) { if (mem_insert(i) == FAILED) return FAILED; if (mem_insert(inz) == FAILED) return FAILED; ind--; } continue; /* DATA & OPTCODE */ case 'd': fscanf(file_out_ptr, "%d", &x); if (mem_insert(x) == FAILED) return FAILED; continue; case 'y': fscanf(file_out_ptr, "%d", &inz); x = inz & 0xFF; inz = (inz >> 8) & 0xFF; if (mem_insert(x) == FAILED) return FAILED; if (mem_insert(inz) == FAILED) return FAILED; continue; /* DATA BLOCK */ case 'D': fscanf(file_out_ptr, "%d %d %d %d", &x, &inz, &z, &y); ifd_tmp = incbin_file_data_first; for (ind = 0; ind != x; ind++) ifd_tmp = ifd_tmp->next; t = ifd_tmp->data + z; /* swap? */ if (inz == 1) { inz = y / 2; for (ind = 0; ind < inz; ind++) { if (mem_insert(*(t + 1)) == FAILED) return FAILED; if (mem_insert(*t) == FAILED) return FAILED; t += 2; } } else { inz = y; for (ind = 0; ind < inz; ind++) { if (mem_insert(*(t++)) == FAILED) return FAILED; } } continue; /* ORIGIN & ROM BANK */ case 'O': case 'B': if (c == 'O') fscanf(file_out_ptr, "%u", &pc_bank); else { fscanf(file_out_ptr, "%u %u", &rom_bank, &slot); if (banksize_defined == 0) banksize = banks[rom_bank]; } pc_full = bankaddress[rom_bank] + pc_bank; pc_slot = slots[slot].address + pc_bank; pc_slot_max = slots[slot].address + slots[slot].size; continue; /* BREAKPOINT */ case 'Z': continue; /* LABEL and SYMBOL */ case 'Y': case 'L': fscanf(file_out_ptr, "%*s"); /* skip the label */ continue; /* 8BIT COMPUTATION */ case 'c': fscanf(file_out_ptr, "%d", &inz); if (bankheader_status == OFF) stacks_tmp = stacks_first; else stacks_tmp = stacks_header_first; while (stacks_tmp != NULL) { if (stacks_tmp->id == inz) break; stacks_tmp = stacks_tmp->next; } if (stacks_tmp == NULL) { fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Could not find computation stack number %d. WLA corruption detected. Please send a bug report!\n", get_file_name(filename_id), line_number, inz); return FAILED; } if (stacks_tmp->section_status == ON) { stacks_tmp->address = sec_tmp->i; /* relative address, to the beginning of the section */ } else { stacks_tmp->address = pc_bank; /* complete address, in ROM memory */ } stacks_tmp->bank = rom_bank; stacks_tmp->slot = slot; stacks_tmp->type = STACKS_TYPE_8BIT; /* this stack was referred from the code */ stacks_tmp->position = STACK_POSITION_CODE; if (mem_insert_pad() == FAILED) return FAILED; continue; /* 16BIT COMPUTATION */ case 'C': fscanf(file_out_ptr, "%d", &inz); if (bankheader_status == OFF) stacks_tmp = stacks_first; else stacks_tmp = stacks_header_first; while (stacks_tmp != NULL) { if (stacks_tmp->id == inz) break; stacks_tmp = stacks_tmp->next; } if (stacks_tmp == NULL) { fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Could not find computation stack number %d. WLA corruption detected. Please send a bug report!\n", get_file_name(filename_id), line_number, inz); return FAILED; } if (stacks_tmp->section_status == ON) { stacks_tmp->address = sec_tmp->i; /* relative address, to the beginning of the section */ } else { stacks_tmp->address = pc_bank; /* complete address, in ROM memory */ } stacks_tmp->bank = rom_bank; stacks_tmp->slot = slot; stacks_tmp->type = STACKS_TYPE_16BIT; /* this stack was referred from the code */ stacks_tmp->position = STACK_POSITION_CODE; if (mem_insert_pad() == FAILED) return FAILED; if (mem_insert_pad() == FAILED) return FAILED; continue; /* 16BIT REFERENCE */ case 'r': fscanf(file_out_ptr, "%256s", tmp); x = 0; tmp_def = defines; while (tmp_def != NULL) { if (strcmp(tmp, tmp_def->alias) == 0) { if (tmp_def->type == DEFINITION_TYPE_STACK) break; if (tmp_def->type == DEFINITION_TYPE_STRING) { fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Reference to a string definition \"%s\"?\n", get_file_name(filename_id), line_number, tmp); return FAILED; } o = tmp_def->value; x = 1; if (mem_insert(o & 0xFF) == FAILED) return FAILED; if (mem_insert((o & 0xFF00) >> 8) == FAILED) return FAILED; break; } tmp_def = tmp_def->next; } if (x == 1) continue; if (new_unknown_reference(REFERENCE_TYPE_DIRECT_16BIT) == FAILED) return FAILED; if (mem_insert_pad() == FAILED) return FAILED; if (mem_insert_pad() == FAILED) return FAILED; continue; /* 8BIT PC RELATIVE REFERENCE */ case 'R': fscanf(file_out_ptr, "%256s", tmp); x = 0; tmp_def = defines; while (tmp_def != NULL) { if (strcmp(tmp, tmp_def->alias) == 0) { if (tmp_def->type == DEFINITION_TYPE_STACK) break; if (tmp_def->type == DEFINITION_TYPE_STRING) { fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Reference to a string definition \"%s\"?\n", get_file_name(filename_id), line_number, tmp); return FAILED; } o = tmp_def->value; x = 1; if (mem_insert(o & 0xFF) == FAILED) return FAILED; break; } tmp_def = tmp_def->next; } if (x == 1) continue; if (new_unknown_reference(REFERENCE_TYPE_RELATIVE_8BIT) == FAILED) return FAILED; if (mem_insert_pad() == FAILED) return FAILED; continue; /* 8BIT REFERENCE */ case 'Q': fscanf(file_out_ptr, "%256s", tmp); x = 0; tmp_def = defines; while (tmp_def != NULL) { if (strcmp(tmp, tmp_def->alias) == 0) { if (tmp_def->type == DEFINITION_TYPE_STACK) break; if (tmp_def->type == DEFINITION_TYPE_STRING) { fprintf(stderr, "%s:%d: INTERNAL_PASS_2: Reference to a string definition \"%s\"?\n", get_file_name(filename_id), line_number, tmp); return FAILED; } o = tmp_def->value; x = 1; if (mem_insert(o & 0xFF) == FAILED) return FAILED; break; } tmp_def = tmp_def->next; } if (x == 1) continue; if (new_unknown_reference(REFERENCE_TYPE_DIRECT_8BIT) == FAILED) return FAILED; if (mem_insert_pad() == FAILED) return FAILED; continue; } } fclose(file_out_ptr); file_out_ptr = NULL; /* library file output */ if (output_format == OUTPUT_LIBRARY && test_mode == OFF) { if ((final_ptr = fopen(final_name, "wb")) == NULL) { fprintf(stderr, "INTERNAL_PASS_2: Error opening file \"%s\".\n", final_name); return FAILED; } /* header */ fprintf(final_ptr, "WLAV"); if (export_source_file_names(final_ptr) == FAILED) return FAILED; /* export definitions */ if (export_definitions(final_ptr) == FAILED) return FAILED; /* labels, symbols and breakpoints */ ov = 0; label_tmp = labels; while (label_tmp != NULL) { if (label_tmp->alive == ON) ov++; label_tmp = label_tmp->next; } WRITEOUT_OV label_tmp = labels; while (label_tmp != NULL) { if (label_tmp->alive == ON) { if (label_tmp->symbol != 2) fprintf(final_ptr, "%s", label_tmp->label); fprintf(final_ptr, "%c", label_tmp->symbol); fprintf(final_ptr, "%c%c", label_tmp->section_id, label_tmp->filename_id); ov = label_tmp->linenumber; WRITEOUT_OV ov = label_tmp->address; WRITEOUT_OV } label_tmp = label_tmp->next; } /* unknown labels */ ov = 0; label_tmp = unknown_labels; while (label_tmp != NULL) { ov++; label_tmp = label_tmp->next; } WRITEOUT_OV label_tmp = unknown_labels; while (label_tmp != NULL) { fprintf(final_ptr, "%s%c%c%c%c", label_tmp->label, 0x0, label_tmp->type, label_tmp->section_id, label_tmp->filename_id); if (label_tmp->section_status == OFF) { fprintf(stderr, "INTERNAL_PASS_2: Label \"%s\" is outside all sections.\n", label_tmp->label); return FAILED; } ov = label_tmp->linenumber; WRITEOUT_OV ov = label_tmp->address; WRITEOUT_OV label_tmp = label_tmp->next; } /* pending calculations */ ov = stacks_outside; WRITEOUT_OV stacks_tmp = stacks_first; while (stacks_tmp != NULL) { ov = stacks_tmp->id; WRITEOUT_OV fprintf(final_ptr, "%c%c%c%c%c", stacks_tmp->type, stacks_tmp->section_id, stacks_tmp->filename_id, stacks_tmp->stacksize, stacks_tmp->position); ov = stacks_tmp->address; WRITEOUT_OV ov = stacks_tmp->linenumber; WRITEOUT_OV for (ind = 0; ind < stacks_tmp->stacksize; ind++) { fprintf(final_ptr, "%c%c", stacks_tmp->stack[ind].type, stacks_tmp->stack[ind].sign); if (stacks_tmp->stack[ind].type == STACK_ITEM_TYPE_STRING) fprintf(final_ptr, "%s%c", stacks_tmp->stack[ind].string, 0); else { dou = stacks_tmp->stack[ind].value; WRITEOUT_DOU } } stacks_tmp = stacks_tmp->next; } /* sections */ sec_tmp = sections_first; while (sec_tmp != NULL) { if (sec_tmp->alive == ON) { fprintf(final_ptr, "%s%c%c%c", sec_tmp->name, sec_tmp->status, sec_tmp->id, sec_tmp->filename_id); ov = sec_tmp->size; WRITEOUT_OV ov = sec_tmp->alignment; WRITEOUT_OV fwrite(sec_tmp->data, 1, sec_tmp->size, final_ptr); if (listfile_data == YES && sec_tmp->listfile_items > 0) listfile_block_write(final_ptr, sec_tmp); else fprintf(final_ptr, "%c", 0); } sec_tmp = sec_tmp->next; } fclose(final_ptr); } /* object file output */ else if (output_format == OUTPUT_OBJECT && test_mode == OFF) { if ((final_ptr = fopen(final_name, "wb")) == NULL) { fprintf(stderr, "INTERNAL_PASS_2: Error opening file \"%s\".\n", final_name); return FAILED; } /* header */ fprintf(final_ptr, "WLAK%c", emptyfill); /* misc bits */ ind = 0; fprintf(final_ptr, "%c", ind); /* more bits */ ind = 0; if (smc_defined != 0) ind += 1; fprintf(final_ptr, "%c", ind); /* rom bank map */ ov = rombanks; WRITEOUT_OV /* number of rom banks */ if (rombankmap_defined != 0) { fprintf(final_ptr, "%c", 1); /* status */ for (i = 0; i < rombanks; i++) { ov = banks[i]; WRITEOUT_OV /* banksize */ } } else { fprintf(final_ptr, "%c", 0); /* status */ ov = banksize; WRITEOUT_OV /* banksize */ } /* memory map */ fprintf(final_ptr, "%c", slots_amount); /* number of slots */ for (i = 0; i < slots_amount; i++) { if (slots[i].size != 0) { ov = slots[i].address; WRITEOUT_OV /* slot address */ ov = slots[i].size; WRITEOUT_OV /* slot size */ } } /* source file names */ if (export_source_file_names(final_ptr) == FAILED) return FAILED; /* export definitions */ if (export_definitions(final_ptr) == FAILED) return FAILED; /* labels */ ov = 0; label_tmp = labels; while (label_tmp != NULL) { if (label_tmp->alive == ON) ov++; label_tmp = label_tmp->next; } /* number of labels */ WRITEOUT_OV label_tmp = labels; while (label_tmp != NULL) { if (label_tmp->alive == ON) { if (label_tmp->symbol != 2) fprintf(final_ptr, "%s", label_tmp->label); fprintf(final_ptr, "%c", label_tmp->symbol); fprintf(final_ptr, "%c%c%c", label_tmp->slot, label_tmp->filename_id, label_tmp->section_id); /* DEBUG fprintf(stderr, "LABEL: \"%s\" SLOT: %d LINE: %d\n", label_tmp->label, label_tmp->slot, label_tmp->linenumber); */ ov = label_tmp->address; WRITEOUT_OV ov = label_tmp->linenumber; WRITEOUT_OV ov = label_tmp->bank; WRITEOUT_OV } label_tmp = label_tmp->next; } /* outside references */ ov = 0; label_tmp = unknown_labels; while (label_tmp != NULL) { ov++; label_tmp = label_tmp->next; } label_tmp = unknown_header_labels; while (label_tmp != NULL) { ov++; label_tmp = label_tmp->next; } WRITEOUT_OV label_tmp = unknown_labels; while (label_tmp != NULL) { fprintf(final_ptr, "%s%c%c%c%c%c", label_tmp->label, 0x0, label_tmp->type, label_tmp->filename_id, label_tmp->slot, label_tmp->section_id); ov = label_tmp->linenumber; WRITEOUT_OV ov = label_tmp->address; WRITEOUT_OV ov = label_tmp->bank; WRITEOUT_OV label_tmp = label_tmp->next; } label_tmp = unknown_header_labels; while (label_tmp != NULL) { fprintf(final_ptr, "%s%c%c%c%c%c", label_tmp->label, 0x0, label_tmp->type, label_tmp->filename_id, label_tmp->slot, label_tmp->section_id); ov = label_tmp->linenumber; WRITEOUT_OV ov = label_tmp->address; WRITEOUT_OV ov = label_tmp->bank; WRITEOUT_OV label_tmp = label_tmp->next; } /* pending calculations */ ov = stacks_outside + stacks_inside; WRITEOUT_OV stacks_tmp = stacks_first; while (stacks_tmp != NULL) { ov = stacks_tmp->id; WRITEOUT_OV fprintf(final_ptr, "%c%c%c%c%c%c", stacks_tmp->type, stacks_tmp->section_id, stacks_tmp->filename_id, stacks_tmp->stacksize, stacks_tmp->position, stacks_tmp->slot); ov = stacks_tmp->address; WRITEOUT_OV ov = stacks_tmp->linenumber; WRITEOUT_OV ov = stacks_tmp->bank; WRITEOUT_OV for (ind = 0; ind < stacks_tmp->stacksize; ind++) { fprintf(final_ptr, "%c%c", stacks_tmp->stack[ind].type, stacks_tmp->stack[ind].sign); if (stacks_tmp->stack[ind].type == STACK_ITEM_TYPE_STRING) fprintf(final_ptr, "%s%c", stacks_tmp->stack[ind].string, 0); else { dou = stacks_tmp->stack[ind].value; WRITEOUT_DOU } } stacks_tmp = stacks_tmp->next; } stacks_tmp = stacks_header_first; while (stacks_tmp != NULL) { fprintf(final_ptr, "%c%c%c%c%c%c", stacks_tmp->type, stacks_tmp->section_id, stacks_tmp->filename_id, stacks_tmp->stacksize, stacks_tmp->position, stacks_tmp->slot); ov = stacks_tmp->address; WRITEOUT_OV ov = stacks_tmp->linenumber; WRITEOUT_OV ov = stacks_tmp->bank; WRITEOUT_OV for (ind = 0; ind < stacks_tmp->stacksize; ind++) { fprintf(final_ptr, "%c%c", stacks_tmp->stack[ind].type, stacks_tmp->stack[ind].sign); if (stacks_tmp->stack[ind].type == STACK_ITEM_TYPE_STRING) fprintf(final_ptr, "%s%c", stacks_tmp->stack[ind].string, 0); else { dou = stacks_tmp->stack[ind].value; WRITEOUT_DOU } } stacks_tmp = stacks_tmp->next; } /* data area */ ind = 0; for (inz = 0; inz < max_address; inz++) { if (rom_banks_usage_table[inz] != 0) { /* data block id */ fprintf(final_ptr, "%c", 0x0); for (i = inz, ind = 0; inz < max_address; inz++, ind++) if (rom_banks_usage_table[inz] == 0) { ov = i; WRITEOUT_OV ov = ind; WRITEOUT_OV fwrite(&rom_banks[i], 1, ind, final_ptr); ind = 0; break; } } } if (ind != 0) { ov = i; WRITEOUT_OV ov = ind; WRITEOUT_OV fwrite(&rom_banks[i], 1, ind, final_ptr); } sec_tmp = sections_first; while (sec_tmp != NULL) { if (sec_tmp->alive == ON) { /* section block id */ fprintf(final_ptr, "%c%s%c%c%c%c", 0x1, sec_tmp->name, sec_tmp->status, sec_tmp->id, sec_tmp->slot, sec_tmp->filename_id); ov = sec_tmp->address; WRITEOUT_OV ov = sec_tmp->bank; WRITEOUT_OV ov = sec_tmp->size; WRITEOUT_OV ov = sec_tmp->alignment; WRITEOUT_OV fwrite(sec_tmp->data, 1, sec_tmp->size, final_ptr); if (listfile_data == YES && sec_tmp->listfile_items > 0) listfile_block_write(final_ptr, sec_tmp); else fprintf(final_ptr, "%c", 0); } sec_tmp = sec_tmp->next; } fclose(final_ptr); } /* output makefile rules */ if (makefile_rules == YES) { fprintf(stderr, "%s: ", final_name); print_file_names(); } /* show project information */ if (verbose_mode == ON && output_format != OUTPUT_LIBRARY) { x = 0; for (ind = 0; ind < max_address; ind++) { if (rom_banks_usage_table[ind] == 0 && x == 0) { x = 1; inz = ind; } else if (rom_banks_usage_table[ind] != 0 && x == 1) { if (inz == (ind - 1)) fprintf(stderr, "Free space at $%.4x.\n", inz); else fprintf(stderr, "Free space at $%.4x-$%.4x.\n", inz, ind - 1); x = 0; } } if (x == 1) { if (inz == (ind - 1)) fprintf(stderr, "Free space at $%.4x.\n", inz); else fprintf(stderr, "Free space at $%.4x-$%.4x.\n", inz, ind - 1); } for (ind = 0, q = 0; ind < max_address; q++) { for (x = 0, inz = 0; inz < banks[q]; inz++) { if (rom_banks_usage_table[ind++] == 0) x++; } f = (((float)x)/banks[q]) * 100.0f; if (f == 100.0f) printf("Bank %.2d has %.5d bytes (%.1f%%) free.\n", q, x, f); else printf("Bank %.2d has %.5d bytes (%.2f%%) free.\n", q, x, f); } for (ind = 0, inz = 0; ind < max_address; ind++) { if (rom_banks_usage_table[ind] == 0) inz++; } fprintf(stderr, "%d unused bytes of total %d.\n", inz, max_address); sec_tmp = sections_first; while (sec_tmp != NULL) { if (sec_tmp->status == SECTION_STATUS_HEADER) { fprintf(stderr, "Bank %d header section size %d.\n", sec_tmp->bank, sec_tmp->size); ind += sec_tmp->size; } sec_tmp = sec_tmp->next; } if (ind != 0) { fprintf(stderr, "Total %d additional bytes (from headers and footers).\n", ind); fprintf(stderr, "Total size %d bytes.\n", ind + max_address); } } else if (verbose_mode == ON && output_format == OUTPUT_LIBRARY) { sec_tmp = sections_first; while (sec_tmp != NULL) { printf("Section \"%s\" size %d.\n", sec_tmp->name, sec_tmp->size); sec_tmp = sec_tmp->next; } } return SUCCEEDED; } int mem_insert(unsigned char x) { if (section_status == ON) { sec_tmp->data[sec_tmp->i] = x; sec_tmp->i++; pc_bank++; pc_full++; pc_slot++; return SUCCEEDED; } if (pc_bank >= banksize) { fprintf(stderr, "MEM_INSERT: Origin ($%x) overflows from bank (%d).\n", pc_bank, rom_bank); return FAILED; } else if (pc_full >= max_address) { fprintf(stderr, "MEM_INSERT: The current address ($%.4x) exceeds the size of the ROM ($%.4x).\n", pc_full, max_address); return FAILED; } else if (pc_slot >= pc_slot_max) { fprintf(stderr, "MEM_INSERT: The current address ($%.4x) overflows from SLOT %d.\n", pc_slot, slot); return FAILED; } if (rom_banks_usage_table[pc_full] != 0 && rom_banks[pc_full] != x && mem_insert_overwrite == OFF) fprintf(stderr, "MEM_INSERT: %d. write into $%.4x (old: $%.2x, new: $%.2x).\n", rom_banks_usage_table[pc_full], pc_full, rom_banks[pc_full], x & 0xFF); rom_banks_usage_table[pc_full] = 2; rom_banks[pc_full] = x; pc_bank++; pc_full++; pc_slot++; return SUCCEEDED; } int mem_insert_pad(void) { if (section_status == ON) { sec_tmp->i++; pc_bank++; pc_full++; pc_slot++; return SUCCEEDED; } if (pc_bank >= banksize) { fprintf(stderr, "MEM_INSERT_PAD: Origin ($%x) overflows from bank (%d).\n", pc_bank, rom_bank); return FAILED; } else if (pc_full >= max_address) { fprintf(stderr, "MEM_INSERT_PAD: The current address ($%.4x) exceeds the size of the ROM ($%.4x).\n", pc_full, max_address); return FAILED; } else if (pc_slot >= pc_slot_max) { fprintf(stderr, "MEM_INSERT_PAD: The current address ($%.4x) overflows from SLOT %d.\n", pc_slot, slot); return FAILED; } /* announce the overwrite later */ if (!(rom_banks_usage_table[pc_full] != 0 && mem_insert_overwrite == OFF)) rom_banks_usage_table[pc_full] = 1; pc_bank++; pc_full++; pc_slot++; return SUCCEEDED; } int mem_insert_absolute(unsigned int add, unsigned char x) { if (add >= max_address) { fprintf(stderr, "MEM_INSERT_ABSOLUTE: The current address ($%.4x) exceeds the size of the ROM ($%.4x).\n", add, max_address); return FAILED; } if (rom_banks_usage_table[add] > 1 && rom_banks[add] != x && mem_insert_overwrite == OFF) fprintf(stderr, "MEM_INSERT_ABSOLUTE: %d. write into $%.4x (old: $%.2x, new: $%.2x).\n", rom_banks_usage_table[add], add, rom_banks[add], x & 0xFF); rom_banks_usage_table[add]++; rom_banks[add] = x; return SUCCEEDED; } int export_definitions(FILE *final_ptr) { struct export_def *export_tmp; unsigned char *cp; double dou; int ov; ov = 0; export_tmp = export_first; while (export_tmp != NULL) { tmp_def = defines; while (tmp_def != NULL) { if (strcmp(tmp_def->alias, export_tmp->name) == 0) { if (tmp_def->type == DEFINITION_TYPE_VALUE) ov++; if (tmp_def->type == DEFINITION_TYPE_STACK) ov++; break; } tmp_def = tmp_def->next; } export_tmp = export_tmp->next; } WRITEOUT_OV export_tmp = export_first; while (export_tmp != NULL) { tmp_def = defines; while (tmp_def != NULL) { if (strcmp(tmp_def->alias, export_tmp->name) == 0) break; tmp_def = tmp_def->next; } if (tmp_def == NULL) fprintf(stderr, "WARNING: Trying to export an unkonwn definition \"%s\".\n", export_tmp->name); else { if (tmp_def->type == DEFINITION_TYPE_VALUE) { fprintf(final_ptr, "%s%c", tmp_def->alias, 0x0); dou = tmp_def->value; WRITEOUT_DOU } else if (tmp_def->type == DEFINITION_TYPE_STRING) { fprintf(stderr, "INTERNAL_PASS_2: Definition \"%s\" is a string definition, and it cannot be exported.\n", export_tmp->name); } else if (tmp_def->type == DEFINITION_TYPE_STACK) { fprintf(final_ptr, "%s%c", tmp_def->alias, 0x1); dou = tmp_def->value; WRITEOUT_DOU } } export_tmp = export_tmp->next; } return SUCCEEDED; } int export_source_file_names(FILE *final_ptr) { struct file_name_info *f; int ov; f = file_name_info_first; ov = 0; while (f != NULL) { ov++; f = f->next; } WRITEOUT_OV f = file_name_info_first; while (f != NULL) { fprintf(final_ptr, "%s%c%c", f->name, 0x00, f->id); f = f->next; } return SUCCEEDED; }
Go to most recent revision | Compare with Previous | Blame | View Log