diff --git a/x65.cpp b/x65.cpp
index 2a3303b..648f736 100644
--- a/x65.cpp
+++ b/x65.cpp
@@ -320,7 +320,7 @@ enum EvalOperator {
 typedef struct sOPLookup {
 	uint32_t op_hash;
 	uint8_t index;	// ground index
-	uint8_t type;		// mnemonic or
+	uint8_t type;	// mnemonic or
 } OPLookup;
 
 enum AddrMode {
@@ -1208,8 +1208,9 @@ typedef struct Section {
 	int align_address;		// for relative sections that needs alignment
 
 	// merged sections
-	int merged_offset;		// -1 if not merged
-	int merged_section;		// which section merged with
+	int merged_at;			// merged into a section at this offset
+	int merged_into;		// -1 if not merged otherwise section merged into
+	int merged_size;		// how many bytes were merged in
 
 	// data output
 	uint8_t *output;	// memory for this section
@@ -1232,7 +1233,8 @@ typedef struct Section {
 		name.clear(); export_append.clear(); include_from.clear();
 		start_address = address = load_address = 0x0; type = ST_CODE;
 		address_assigned = false; output = nullptr; curr = nullptr;
-		dummySection = false; output_capacity = 0; merged_offset = -1; merged_section = -1;
+		dummySection = false; output_capacity = 0;
+		merged_at = -1; merged_into = -1; merged_size = 0;
 		align_address = 1; if (pRelocs) delete pRelocs;
 		next_group = first_group = -1;
 		pRelocs = nullptr;
@@ -1241,7 +1243,7 @@ typedef struct Section {
 	}
 
 	void Cleanup() { if (output) free(output); reset(); }
-	bool empty() const { return merged_offset<0 && curr==output; }
+	bool empty() const { return type != ST_REMOVED && curr==output; }
 	bool unused() const { return !address_assigned && address == start_address; }
 
 	int DataOffset() const { return int(curr - output); }
@@ -1257,7 +1259,7 @@ typedef struct Section {
 	void SetDummySection(bool enable) { dummySection = enable; type = ST_BSS;  }
 	bool IsDummySection() const { return dummySection; }
 	bool IsRelativeSection() const { return address_assigned == false; }
-	bool IsMergedSection() const { return merged_offset >= 0; }
+	bool IsMergedSection() const { return false; }
 	void AddReloc(int base, int offset, int section, int8_t bytes, int8_t shift);
 
 	Section() : pRelocs(nullptr), pListing(nullptr) { reset(); }
@@ -2128,8 +2130,9 @@ uint8_t* Asm::BuildExport(strref append, int &file_size, int &addr) {
 
 	// copy over in order
 	for (std::vector<Section>::iterator i = allSections.begin(); i != allSections.end(); ++i) {
+		if (i->type == ST_REMOVED) { continue; }
 		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) {
+			if (i->start_address>=0x200&&i->size()>0) {
 				memcpy(output+i->start_address-start_address, i->output, i->size());
 			}
 		}
@@ -2273,10 +2276,6 @@ StatusCode Asm::LinkRelocs(int section_id, int section_new, int section_address)
 				if (i->target_section == section_id) {
 					Section *trg_sect = &s2;
 					size_t output_offs = 0;
-					while (trg_sect->merged_offset>=0) {
-						output_offs += trg_sect->merged_offset;
-						trg_sect = &allSections[trg_sect->merged_section];
-					}
 					// only finalize the target value if fixed address
 					if (section_new == -1 || allSections[section_new].address_assigned) {
 						uint8_t *trg = trg_sect->output + output_offs + i->section_offset;
@@ -2366,6 +2365,8 @@ StatusCode Asm::MergeSections(int section_id, int section_merge) {
 		return ERROR_CANT_APPEND_SECTION_TO_TARGET;
 	}
 
+	m.merged_size = m.address - m.start_address;
+
 	// append the binary to the target..
 	int addr_start = s.address;
 	int align = m.align_address <= 1 ? 0 : (m.align_address - (addr_start % m.align_address)) % m.align_address;
@@ -2382,6 +2383,10 @@ StatusCode Asm::MergeSections(int section_id, int section_merge) {
 
 	addr_start += align - s.start_address;
 
+	// append info for result output
+	m.merged_at = addr_start;
+	m.merged_into = section_id;
+
 	// move the relocs from the merge section to the keep section
 	if (m.pRelocs) {
 		if (!s.pRelocs) { s.pRelocs = new relocList; }
@@ -3581,10 +3586,6 @@ StatusCode Asm::CheckLateEval(strref added_label, int scope_end, bool print_miss
 					int trg = i->target;
 					int sec = i->section;
 					if (i->type != LateEval::LET_LABEL) {
-						if (allSections[sec].IsMergedSection()) {
-							trg += allSections[sec].merged_offset;
-							sec = allSections[sec].merged_section;
-						}
 					}
 					bool resolved = true;
 					switch (i->type) {
@@ -5865,9 +5866,52 @@ bool Asm::List(strref filename) {
 	int16_t cycles_depth = 0;
 	memset(cycles, 0, sizeof(cycles));
 
+
+	// show merged sections
+	for (size_t i = 0, n = allSections.size(); i < n; ++i)
+	{
+		Section& s = allSections[i];
+		if (s.type != ST_REMOVED) {
+			if (s.include_from) {
+				fprintf(f, "Section " STRREF_FMT " from " STRREF_FMT " $%04x - $%04x ($%04x)\n",
+					STRREF_ARG(s.name), STRREF_ARG(s.include_from), s.start_address, s.address, s.address - s.start_address);
+			} else {
+				fprintf(f, "Section " STRREF_FMT " $%04x - $%04x ($%04x)\n",
+					STRREF_ARG(s.name), s.start_address, s.address, s.address - s.start_address);
+			}
+			for (size_t j = 0; j < n; ++j)
+			{
+				Section& s2 = allSections[j];
+				if (s2.type == ST_REMOVED && s2.merged_into >= 0)
+				{
+					int offset = s2.merged_at;
+					int parent = s2.merged_into;
+					while (parent != i && parent >= 0) {
+						offset += allSections[parent].merged_at;
+						parent = allSections[parent].merged_into;
+					}
+					if (parent == i) {
+						if (s2.include_from) {
+							fprintf(f, " + " STRREF_FMT " from " STRREF_FMT " $%04x - $%04x ($%04x) at offset 0x%04x\n",
+								STRREF_ARG(s2.name), STRREF_ARG(s2.include_from), s2.merged_at + s.start_address,
+								s2.merged_at + s.start_address + s2.merged_size, s2.merged_size, s2.merged_at);
+						} else {
+							fprintf(f, " + " STRREF_FMT " $%04x - $%04x ($%04x) at offset 0x%04x\n",
+								STRREF_ARG(s2.name), s2.merged_at + s.start_address,
+								s2.merged_at + s.start_address + s2.merged_size, s2.merged_size, s2.merged_at);
+						}
+					}
+				}
+			}
+		}
+	}
+
 	strref prev_src;
 	int prev_offs = 0;
 	for (std::vector<Section>::iterator si = allSections.begin(); si != allSections.end(); ++si) {
+		if (si->merged_into >= 0) {
+			fprintf(f, STRREF_FMT " from " STRREF_FMT " merged into " STRREF_FMT " at offset 0x%04x\n",
+			STRREF_ARG(si->name), STRREF_ARG(si->include_from), STRREF_ARG(allSections[si->merged_into].name), si->merged_at); }
 		if (si->type==ST_REMOVED) { continue; }
 		if (si->address_assigned)
 			fprintf(f, "Section " STRREF_FMT " (%d, %s): $%04x-$%04x\n", STRREF_ARG(si->name),
@@ -7036,17 +7080,7 @@ int main(int argc, char **argv) {
 					if (FILE *f = fopen(sym_file, "w")) {
 						bool wasLocal = false;
 						for (MapSymbolArray::iterator i = assembler.map.begin(); i!=assembler.map.end(); ++i) {
-							uint32_t value = (uint32_t)i->value;
-							int section = i->section;
-							while (section >= 0 && section < (int)assembler.allSections.size()) {
-								if (assembler.allSections[section].IsMergedSection()) {
-									value += assembler.allSections[section].merged_offset;
-									section = assembler.allSections[section].merged_section;
-								} else {
-									value += assembler.allSections[section].start_address;
-									break;
-								}
-							}
+							uint32_t value = (uint32_t)i->value + assembler.allSections[i->section].start_address;
 							fprintf(f, "%s.label " STRREF_FMT " = $%04x", wasLocal==i->local ? "\n" :
 									(i->local ? " {\n" : "\n}\n"), STRREF_ARG(i->name), value);
 							wasLocal = i->local;
@@ -7060,17 +7094,7 @@ int main(int argc, char **argv) {
 				if (vs_file && !srcname.same_str(vs_file) && !assembler.map.empty()) {
 					if (FILE *f = fopen(vs_file, "w")) {
 						for (MapSymbolArray::iterator i = assembler.map.begin(); i!=assembler.map.end(); ++i) {
-							uint32_t value = (uint32_t)i->value;
-							int section = i->section;
-							while (section >= 0 && section < (int)assembler.allSections.size()) {
-								if (assembler.allSections[section].IsMergedSection()) {
-									value += assembler.allSections[section].merged_offset;
-									section = assembler.allSections[section].merged_section;
-								} else {
-									value += assembler.allSections[section].start_address;
-									break;
-								}
-							}
+							uint32_t value = (uint32_t)i->value + assembler.allSections[i->section].start_address;
 							if(i->name.same_str("debugbreak")) {
 								fprintf(f, "break $%04x\n", value);
 							} else {