diff --git a/README.md b/README.md index 6eb9220..b2dacbc 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ x65 filename.s code.prg [options] * -cpu=6502/6502ill/65c02/65c02wdc/65816: assemble with opcodes for a different cpu * -acc=8/16: start assembling with accumulator immediate mode instruction size 8 or 16 bits * -xy=8/16: start assembling with index register immediate mode instruction size 8 or 16 bits +* -org=$2000 or -org=4096: set the default start address of fixed address code * -obj (file.x65): generate object file for later linking * -bin: Raw binary * -c64: Include load address (default) @@ -921,11 +922,12 @@ Fish food! Assembler has all important features and switching to make a 6502 pro **TODO** * Rather than keeping track of merged section for fixed address linking, just append the user linked section to the current section and empty the old section. -* -org command line argument to override the built-in assumption of org $1000, to avoid ever having to use the ORG directive inlined in code. * OMF export for Apple II GS/OS executables * irp (indefinite repeat) **FIXED** +* Fixed linker merged section reloc confusion. +* -org command line argument to override the built-in assumption of org $1000, to avoid ever having to use the ORG directive inlined in code. * dump_x65 now shows the code offset of each section into the .x65 file which can be copied and pasted into the disassembler in case the object file assembler output needs to be inspected. * A linker export summary is shown when building binary fixed address, this shows how the linker re-arranged the sections in memory. The section addresses are also included in the .lst file even if the section didn't generate any listing information, such as included object files. * BSS sections are handled similar to CODE and DATA sections but will not write out BSS bytes at end of binary data. This should complete the section handling necessary to build a relocatable executable. diff --git a/dump_x65/dump_x65.cpp b/dump_x65/dump_x65.cpp index 83d17c1..6d66e7c 100644 --- a/dump_x65/dump_x65.cpp +++ b/dump_x65/dump_x65.cpp @@ -168,8 +168,6 @@ enum LEType { // When an expression is evaluated late, determine how to encode LET_BYTE, // calculate a byte and store at this address }; -static const char *reloc_type[] = { - "NONE", "WORD", "LO_BYTE", "HI_BYTE" }; static const char *late_type[] = { "LABEL", "ABS_REF", "ABS_L_REF", "ABS_4_REF", "BRANCH", "BRANCH_16", "BYTE" }; @@ -236,7 +234,7 @@ void ReadObjectFile(const char *file, unsigned int show = SHOW_DEFAULT) if (s.next_group >= 0) printf(" next in group: %d", s.next_group); if ((show & SHOW_CODE_RANGE) && s.output_size) - printf(" code: $%x-$%x", code_curr, code_curr + s.output_size); + printf(" code: $%x-$%x", (int)code_curr, (int)(code_curr + s.output_size)); code_curr += s.output_size; printf("\n"); reloc_idx++; @@ -311,7 +309,6 @@ void ReadObjectFile(const char *file, unsigned int show = SHOW_DEFAULT) int main(int argc, char **argv) { const char *file = nullptr; - bool def = true; unsigned int show = 0; for (int a = 1; a FixedExport; @@ -1928,7 +1929,6 @@ unsigned char* Asm::BuildExport(strref append, int &file_size, int &addr) start_address = i->start_address; if ((i->start_address + (int)i->size()) > end_address) { end_address = i->start_address + (int)i->size(); - last_fixed_section = section_id; } } } @@ -1941,7 +1941,7 @@ unsigned char* Asm::BuildExport(strref append, int &file_size, int &addr) if (!has_fixed_section) { // there is not a fixed section so go through and assign addresses to all sections // starting with the first reasonable section - start_address = 0x1000; + start_address = default_org; if (first_link_section < 0) return nullptr; while (first_link_section >= 0) { @@ -2010,7 +2010,7 @@ unsigned char* Asm::BuildExport(strref append, int &file_size, int &addr) // copy over in order for (std::vector
::iterator i = allSections.begin(); i != allSections.end(); ++i) { - if ((!append && !i->export_append) || append.same_str_case(i->export_append) && i->type != ST_ZEROPAGE) { + if (((!append && !i->export_append) || append.same_str_case(i->export_append)) && i->type != ST_ZEROPAGE) { if (i->merged_offset == -1 && i->start_address >= 0x200 && i->size() > 0) memcpy(output + i->start_address - start_address, i->output, i->size()); } @@ -2171,8 +2171,6 @@ StatusCode Asm::LinkRelocs(int section_id, int section_new, int section_address) while (trg_sect->merged_offset>=0) { output_offs += trg_sect->merged_offset; trg_sect = &allSections[trg_sect->merged_section]; - i->target_section = section_new; - i->section_offset += section_address; } // only finalize the target value if fixed address if (section_new == -1 || allSections[section_new].address_assigned) { @@ -2603,10 +2601,12 @@ StatusCode Asm::BuildMacro(Macro &m, strref arg_list) strovl macexp(buffer, mac_size); macexp.copy(macro_src); arg = arg_list; - for (int t=1; t=(MAX_SCOPE_DEPTH-1)) @@ -3756,7 +3756,7 @@ StatusCode Asm::AssignLabel(strref label, strref line, bool make_constant) struct EvalContext etx; SetEvalCtxDefaults(etx); StatusCode status = EvalExpression(line, etx, val); - if (status != STATUS_NOT_READY && status != STATUS_OK) + if (status != STATUS_NOT_READY && status != STATUS_OK && status != STATUS_RELATIVE_SECTION) return status; Label *pLabel = GetLabel(label); @@ -3768,8 +3768,8 @@ StatusCode Asm::AssignLabel(strref label, strref line, bool make_constant) pLabel->label_name = label; pLabel->pool_name.clear(); - pLabel->evaluated = status==STATUS_OK; - pLabel->section = -1; // assigned labels are section-less + pLabel->evaluated = status==STATUS_OK || status == STATUS_RELATIVE_SECTION; + pLabel->section = status == STATUS_RELATIVE_SECTION ? lastEvalSection : -1; // assigned labels are section-less pLabel->value = val; pLabel->mapIndex = -1; pLabel->pc_relative = false; @@ -5352,7 +5352,8 @@ bool Asm::List(strref filename) for (std::vector
::iterator si = allSections.begin(); si != allSections.end(); ++si) { if (si->address_assigned) fprintf(f, "Section " STRREF_FMT " (%d, %s): $%04x-$%04x\n", STRREF_ARG(si->name), - (int)(&*si - &allSections[0]), str_section_type[si->type], si->start_address, si->address); + (int)(&*si - &allSections[0]), si->type>=0 && si->typetype] : "???", si->start_address, si->address); else fprintf(f, "Section " STRREF_FMT " (%d, %s) (relocatable)\n", STRREF_ARG(si->name), (int)(&*si - &allSections[0]), str_section_type[si->type]); @@ -5539,6 +5540,8 @@ void Asm::Assemble(strref source, strref filename, bool obj_target) if (link_all_section) LinkAllToSection(); if (error == STATUS_OK) { + if (!obj_target) + LinkZP(); error = CheckLateEval(); if (error > STATUS_XREF_DEPENDENT) { strown<512> errorText; @@ -6031,6 +6034,7 @@ int main(int argc, char **argv) const strref cpu("cpu"); const strref acc("acc"); const strref xy("xy"); + const strref org("org"); int return_value = 0; bool load_header = true; bool size_header = false; @@ -6075,6 +6079,10 @@ int main(int argc, char **argv) } else if (arg.has_prefix(allinstr) && (arg.get_len() == allinstr.get_len() || arg[allinstr.get_len()] == '=')) { gen_allinstr = true; allinstr_file = arg.after('='); + } else if (arg.has_prefix(org)) { + arg = arg.after('='); + if (arg && arg.get_first() == '$') assembler.default_org = (arg + 1).ahextoui(); + else if (arg.is_number()) assembler.default_org = arg.atoi(); } else if (arg.has_prefix(acc) && arg[acc.get_len()] == '=') { assembler.accumulator_16bit = arg.after('=').atoi() == 16; } else if (arg.has_prefix(xy) && arg[xy.get_len()] == '=') { @@ -6120,6 +6128,7 @@ int main(int argc, char **argv) " * -cpu=6502/65c02/65c02wdc/65816: assemble with opcodes for a different cpu\n" " * -acc=8/16: set the accumulator mode for 65816 at start, default is 8 bits\n" " * -xy=8/16: set the index register mode for 65816 at start, default is 8 bits\n" + " * -org = $2000 or - org = 4096: set the default start address of fixed address code\n" " * -obj (file.x65) : generate object file for later linking\n" " * -bin : Raw binary\n" " * -c64 : Include load address(default)\n" @@ -6147,9 +6156,9 @@ int main(int argc, char **argv) assembler.Assemble(strref(buffer, strl_t(size)), srcname, obj_out_file != nullptr); - if (assembler.error_encountered) + /*if (assembler.error_encountered) return_value = 1; - else { + else*/ { // export object file if (obj_out_file) assembler.WriteObjectFile(obj_out_file);